#include <polygon.h>
Definition at line 122 of file polygon.h.
Public Types | |
typedef std::pair< sint, sint > | TRaster |
typedef std::vector< TRaster > | TRasterVect |
typedef std::vector< CVector2f > | TVec2fVect |
Public Member Functions | |
void | buildConvexHull (CPolygon2D &dest) const |
void | computeBorders (TRasterVect &borders, sint &minimumY) |
void | computeInnerBorders (TRasterVect &borders, sint &minimumY) |
void | computeOuterBorders (TRasterVect &borders, sint &minimumY) |
bool | contains (const CVector2f &p) const |
Check wether a point is contained by this poly. | |
CPolygon2D (const CTriangle &tri, const CMatrix &projMat=CMatrix::Identity) | |
CPolygon2D (const CPolygon &src, const CMatrix &projMat=CMatrix::Identity) | |
CPolygon2D () | |
default ctor | |
void | getBestTriplet (uint &index0, uint &index1, uint &index2) |
get the best triplet of vector. e.g the triplet that has the best surface | |
void | getLineEquation (uint index, float &a, float &b, float &c) const |
Get a line equation of the seg starting at the given index. | |
bool | getNonNullSeg (uint &seg) const |
bool | intersect (const CPolygon2D &other) const |
Test wether this polygon intersect another convex polygon. Currently not optimized. | |
bool | isConvex () |
Check wether this polygon is convex;. | |
void | serial (NLMISC::IStream &f) throw (NLMISC::EStream) |
Serial this polygon. | |
void | swap (CPolygon2D &other) |
Data Fields | |
TVec2fVect | Vertices |
Private Member Functions | |
const CVector2f & | getSegRef0 (uint index) const |
Get ref to the first vertex that start at index. | |
const CVector2f & | getSegRef1 (uint index) const |
float | sumDPAgainstLine (float a, float b, float c) const |
Sum the dot product of this poly vertices against a plane. |
|
Definition at line 159 of file polygon.h. Referenced by RenderTriangle(), NLMISC::ScanInnerEdge(), NLMISC::ScanOuterEdgeLeft(), and NLMISC::ScanOuterEdgeRight(). |
|
Definition at line 160 of file polygon.h. Referenced by NL3D::CLodCharacterShapeBuild::compile(), computeBorders(), computeInnerBorders(), computeOuterBorders(), RenderTriangle(), NL3D::CRenderZBuffer::run(), NLMISC::ScanEdge(), and NL3D::CWaterModel::traverseRender(). |
|
Definition at line 125 of file polygon.h. Referenced by computeBorders(), NLMISC::Next(), and NLMISC::Prev(). |
|
default ctor
Definition at line 129 of file polygon.h.
00129 {} |
|
Build a 2D polygon from this 3D polygon, by using the given projection matrix The x and y components of projected vertices are used to create the 2D polygon Definition at line 785 of file polygon.cpp. References size, src, uint, NLMISC::CVector::x, and NLMISC::CVector::y.
|
|
Build a 2D polygon from the given triangle, by using the given projection matrix The x and y components of projected vertices are used to create the 2D polygon Definition at line 1928 of file polygon.cpp. References NLMISC::CTriangle::V0, NLMISC::CTriangle::V1, NLMISC::CTriangle::V2, x, and y.
|
|
Build a convex hull from this polygon. The result poly is ordered, so it can also be used to order a convex poly given its set of vertices. NB: require this != &dest Definition at line 836 of file polygon.cpp. References nlassert, uint, Vertices, and NLMISC::CVector2f::y.
00837 { 00838 nlassert(&dest != this); 00839 00840 if (this->Vertices.size() == 3) // with 3 points it is always convex 00841 { 00842 dest = *this; 00843 return; 00844 } 00845 uint k, l; 00846 uint numVerts = Vertices.size(); 00847 CVector2f p, curr, prev; 00848 uint pIndex, p1Index, p2Index, pCurr, pPrev; 00849 // this is not optimized, but not used in realtime.. =) 00850 nlassert(numVerts >= 3); 00851 dest.Vertices.clear(); 00852 00853 typedef std::set<uint> TIndexSet; 00854 TIndexSet leftIndex; 00855 for (k = 0; k < Vertices.size(); ++k) 00856 { 00857 leftIndex.insert(k); 00858 } 00859 00860 00861 // 1) find the highest point p of the set. We are sure it belongs to the hull 00862 pIndex = 0; 00863 p = Vertices[0]; 00864 for (k = 1; k < numVerts; ++k) 00865 { 00866 if (Vertices[k].y < p.y) 00867 { 00868 pIndex = k; 00869 p = Vertices[k]; 00870 } 00871 } 00872 00873 leftIndex.erase(pIndex); 00874 00875 00876 float bestCP = 1.1f; 00877 p1Index = p2Index = pIndex; 00878 00879 for (k = 0; k < numVerts; ++k) 00880 { 00881 if (k != pIndex) 00882 { 00883 for (l = 0; l < numVerts; ++l) 00884 { 00885 if (l != pIndex && l != k) 00886 { 00887 CVector2f seg1 = (Vertices[l] - p).normed(); 00888 CVector2f seg2 = (Vertices[k] - p).normed(); 00889 00890 //CVector cp = CVector(seg1.x, seg1.y, 0) ^ CVector(seg2.x, seg2.y, 0); 00891 //float n = fabsf(cp.z); 00892 float n = seg1 * seg2; 00893 if (n < bestCP) 00894 { 00895 p1Index = l; 00896 p2Index = k; 00897 bestCP = n; 00898 } 00899 } 00900 } 00901 } 00902 } 00903 00904 00905 leftIndex.erase(p2Index); 00906 00907 00908 00909 // start from the given triplet, and complete the poly until we reach the first point 00910 pCurr = p2Index; 00911 pPrev = pIndex; 00912 00913 curr = Vertices[pCurr]; 00914 prev = Vertices[pPrev]; 00915 00916 // create the first triplet vertices 00917 dest.Vertices.push_back(Vertices[p1Index]); 00918 dest.Vertices.push_back(prev); 00919 dest.Vertices.push_back(curr); 00920 00921 uint step = 0; 00922 00923 for(;;) 00924 { 00925 bestCP = 1.1f; 00926 CVector2f seg2 = (prev - curr).normed(); 00927 TIndexSet::const_iterator bestIt = leftIndex.end(); 00928 for (TIndexSet::const_iterator it = leftIndex.begin(); it != leftIndex.end(); ++it) 00929 { 00930 if (step == 0 && *it == p1Index) continue; 00931 CVector2f seg1 = (Vertices[*it] - curr).normed(); 00932 float n = seg1 * seg2; 00933 if (n < bestCP) 00934 { 00935 bestCP = n; 00936 bestIt = it; 00937 } 00938 } 00939 00940 nlassert(bestIt != leftIndex.end()); 00941 if (*bestIt == p1Index) 00942 { 00943 return; // if we reach the start point we have finished 00944 } 00945 prev = curr; 00946 curr = Vertices[*bestIt]; 00947 pPrev = pCurr; 00948 pCurr = *bestIt; 00949 // add new point to the destination 00950 dest.Vertices.push_back(curr); 00951 ++step; 00952 leftIndex.erase(bestIt); 00953 } 00954 } |
|
Compute the borders of this poly with sub-pixel accuracy. No clipping is performed. Only points exactly inside or exactly on the left border of the polygon are kept. This means that pixels are seen as points, not as surfaces. The output is in a vector of sint pairs. minimumY is filled with the minimum y value of the poly. Each pairs gives [xmin, xmax] for the current segment. if xmin > xmax, then no point is valid for this segment. Otherwise, all points from x = xmin (included) to x = xmax (included) are valids. Definition at line 1075 of file polygon.cpp. References NLMISC::Next(), NLMISC::Prev(), NLMISC::ScanEdge(), sint, TRasterVect, TVec2fVect, and uint. Referenced by NL3D::CLodCharacterShapeBuild::compile(), RenderTriangle(), and NL3D::CWaterModel::traverseRender().
01076 { 01077 // an 'alias' to the vertices 01078 const TVec2fVect &V = Vertices; 01079 if (Vertices.size() < 3) 01080 { 01081 borders.clear(); 01082 return; 01083 } 01084 bool ccw; // set to true when it has a counter clock wise orientation 01085 01086 // compute highest and lowest pos of the poly 01087 float fHighest = V[0].y; 01088 float fLowest = fHighest; 01089 01090 // iterators to the thighest and lowest vertex 01091 TVec2fVect::const_iterator pLowest = V.begin(), pHighest = V.begin(); 01092 TVec2fVect::const_iterator it = V.begin() ; 01093 const TVec2fVect::const_iterator endIt = V.end(); 01094 do 01095 { 01096 if (it->y > fLowest) 01097 { 01098 fLowest = it->y; 01099 pLowest = it; 01100 } 01101 else 01102 if (it->y < fHighest) 01103 { 01104 fHighest = it->y; 01105 pHighest = it; 01106 } 01107 ++it; 01108 } 01109 while (it != endIt); 01110 01111 01112 sint iHighest = (sint) ceilf(fHighest) ; 01113 sint iLowest = (sint) ceilf(fLowest) ; 01114 01115 highestY = iHighest; 01116 01117 01119 uint polyHeight = iLowest - iHighest; 01120 if (polyHeight <= 0) 01121 { 01122 borders.clear(); 01123 return; 01124 } 01125 01126 borders.resize(polyHeight); 01127 01128 // iterator to the first vertex that has an y different from the top vertex 01129 TVec2fVect::const_iterator pHighestRight = pHighest; 01130 // we seek this vertex 01131 while (Next(pHighestRight, V)->y == fHighest) 01132 { 01133 pHighestRight = Next(pHighestRight, V); 01134 } 01135 01136 // iterator to the first vertex after pHighestRight, that has the same y than the highest vertex 01137 TVec2fVect::const_iterator pHighestLeft = Next(pHighestRight, V); 01138 // seek the vertex 01139 while (pHighestLeft->y != fHighest) 01140 { 01141 pHighestLeft = Next(pHighestLeft, V); 01142 } 01143 01144 TVec2fVect::const_iterator pPrevHighestLeft = Prev(pHighestLeft, V); 01145 01146 // we need to get the orientation of the polygon 01147 // There are 2 case : flat, and non-flat top 01148 01149 // check for flat top 01150 if (pHighestLeft->x != pHighestRight->x) 01151 { 01152 // compare right and left side 01153 if (pHighestLeft->x > pHighestRight->x) 01154 { 01155 ccw = true; // the list is CCW oriented 01156 std::swap(pHighestLeft, pHighestRight); 01157 } 01158 else 01159 { 01160 ccw = false; // the list is CW oriented 01161 } 01162 } 01163 else 01164 { 01165 // The top of the poly is sharp 01166 // We perform a cross product of the 2 highest vect to get its orientation 01167 01168 const float deltaXN = Next(pHighestRight, V)->x - pHighestRight->x; 01169 const float deltaYN = Next(pHighestRight, V)->y - pHighestRight->y; 01170 const float deltaXP = pPrevHighestLeft->x - pHighestLeft->x; 01171 const float deltaYP = pPrevHighestLeft->y - pHighestLeft->y; 01172 if ((deltaXN * deltaYP - deltaYN * deltaXP) < 0) 01173 { 01174 ccw = true; // the list is CCW oriented 01175 std::swap(pHighestLeft, pHighestRight); 01176 } 01177 else 01178 { 01179 ccw = false; // the list is CW oriented 01180 } 01181 } 01182 01183 01184 // compute borders 01185 TVec2fVect::const_iterator currV, nextV; // current and next vertex 01186 if (!ccw) // clock wise order ? 01187 { 01188 currV = pHighestRight ; 01189 // compute right edge from top to bottom 01190 do 01191 { 01192 nextV = Next(currV, V); 01193 ScanEdge(borders, iHighest, *currV, *nextV, true); 01194 currV = nextV; 01195 } 01196 while (currV != pLowest); // repeat until we reach the bottom vertex 01197 01198 // compute left edge from bottom to top 01199 do 01200 { 01201 nextV = Next(currV, V); 01202 ScanEdge(borders, iHighest, *nextV, *currV, false); 01203 currV = nextV; 01204 } 01205 while (currV != pHighestLeft); 01206 } 01207 else // ccw order 01208 { 01209 currV = pHighestLeft; 01210 // compute left edge from top to bottom 01211 do 01212 { 01213 nextV = Next(currV, V); 01214 ScanEdge(borders, iHighest, *currV, *nextV, false) ; 01215 currV = nextV; 01216 } 01217 while (currV != pLowest) ; 01218 01219 // compute right edge from bottom to top 01220 do 01221 { 01222 nextV = Next(currV, V); 01223 ScanEdge(borders, iHighest, *nextV, *currV, true); 01224 currV = nextV; 01225 } 01226 while (currV != pHighestRight) ; 01227 } 01228 } |
|
The same as compute borders, but pixel are seen as surfaces and not as points In this version, only pixels that are entirely INSIDE the poly are kept Definition at line 1618 of file polygon.cpp. References min, NLMISC::ScanInnerEdge(), sint, TRasterVect, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.
01619 { 01620 if (Vertices.empty()) 01621 { 01622 borders.clear(); 01623 minimumY = -1; 01624 return; 01625 } 01626 const CVector2f *first = &Vertices[0]; 01627 const CVector2f *last = first + Vertices.size(); 01628 01629 const CVector2f *curr = first, *next, *plowest ,*phighest; 01630 const CVector2f *pHighestRight, *pHighestRightNext, *pHighestLeft; 01631 const CVector2f *pPrevHighestLeft; 01632 double deltaXN, deltaYN, deltaXP, deltaYP; 01633 bool ccw; // true if CCW oriented 01634 sint polyHeight; 01635 sint highest, lowest; 01636 01637 float fright = curr->x; 01638 float fleft = curr->x; 01639 float fhighest = curr->y; 01640 float flowest = curr->y; 01641 plowest = phighest = curr; 01642 01643 // compute highest (with lowest y) and lowest (with highest y) points of the poly 01644 do 01645 { 01646 fright = std::max(fright, curr->x); 01647 fleft = std::min(fleft, curr->x); 01648 if (curr->y > flowest) 01649 { 01650 flowest = curr->y; 01651 plowest = curr; 01652 } 01653 if (curr->y < fhighest) 01654 { 01655 fhighest = curr->y; 01656 phighest = curr; 01657 } 01658 ++curr; 01659 } 01660 while (curr != last); 01661 01662 01663 highest = (sint) floorf(fhighest); 01664 lowest = (sint) ceilf(flowest); 01665 01666 polyHeight = lowest - highest; 01667 if (polyHeight == 0) return; 01668 01669 // make room for rasters 01670 borders.resize(polyHeight); 01671 // fill with xmin / xman 01672 sint ileft = (sint) floorf(fleft) - 1; 01673 sint iright = (sint) ceilf(fright); 01674 for(TRasterVect::iterator it = borders.begin(); it != borders.end(); ++it) 01675 { 01676 it->second = iright; 01677 it->first = ileft; 01678 } 01679 01680 minimumY = highest; 01681 pHighestRight = phighest; 01682 for (;;) 01683 { 01684 pHighestRightNext = pHighestRight + 1; 01685 if (pHighestRightNext == last) pHighestRightNext = first; 01686 if (pHighestRightNext->y != pHighestRight->y) break; 01687 pHighestRight = pHighestRightNext; 01688 } 01689 01690 pPrevHighestLeft = pHighestRight; 01691 pHighestLeft = pHighestRight; 01692 ++pHighestLeft; 01693 if (pHighestLeft == last) pHighestLeft = first; 01694 01695 while (pHighestLeft->y != fhighest) 01696 { 01697 pPrevHighestLeft = pHighestLeft; 01698 ++pHighestLeft; 01699 if (pHighestLeft == last) pHighestLeft = first; 01700 } 01701 01702 01703 // we need to get the orientation of the polygon 01704 // There are 2 case : flat, and non-flat top 01705 01706 // check for flat top 01707 if (pHighestLeft->x != pHighestRight->x) 01708 { 01709 // compare right and left side 01710 if (pHighestLeft->x > pHighestRight->x) 01711 { 01712 ccw = true; // the list is CCW oriented 01713 std::swap(pHighestLeft, pHighestRight); 01714 } 01715 else 01716 { 01717 ccw = false; // the list is CW oriented 01718 } 01719 } 01720 else 01721 { 01722 pHighestRightNext = pHighestRight + 1; 01723 if (pHighestRightNext == last) pHighestRightNext = first; 01724 deltaXN = pHighestRightNext->x - pHighestRight->x; 01725 deltaYN = pHighestRightNext->y - pHighestRight->y; 01726 deltaXP = pPrevHighestLeft->x - pHighestLeft->x; 01727 deltaYP = pPrevHighestLeft->y - pHighestLeft->y; 01728 if ((deltaXN * deltaYP - deltaYN * deltaXP) < 0) 01729 { 01730 ccw = true; 01731 std::swap(pHighestLeft, pHighestRight); 01732 } 01733 else 01734 { 01735 ccw = false; 01736 } 01737 } 01738 01739 if (!ccw) 01740 { 01741 // cw oriented 01742 curr = pHighestRight; 01743 do 01744 { 01745 next = curr + 1; 01746 if (next == last) next = first; 01747 ScanInnerEdge(&borders[0], curr->x, curr->y, next->x, next->y, minimumY, true); 01748 curr = next; 01749 } 01750 while (curr != plowest); 01751 do 01752 { 01753 next = curr + 1; 01754 if (next == last) next = first; 01755 ScanInnerEdge(&borders[0], next->x, next->y, curr->x, curr->y, minimumY, false); 01756 curr = next; 01757 } 01758 while (curr != pHighestLeft); 01759 } 01760 else 01761 { 01762 // ccw oriented 01763 curr = pHighestLeft; 01764 do 01765 { 01766 next = curr + 1; 01767 if (next == last) next = first; 01768 ScanInnerEdge(&borders[0], curr->x, curr->y, next->x, next->y, minimumY, false); 01769 curr = next; 01770 } 01771 while (curr != plowest); 01772 do 01773 { 01774 next = curr + 1; 01775 if (next == last) next = first; 01776 ScanInnerEdge(&borders[0], next->x, next->y, curr->x, curr->y, minimumY, true); 01777 curr = next; 01778 } 01779 while (curr != pHighestRight); 01780 } 01781 // fix for top 01782 if (floorf(fhighest) != fhighest) 01783 { 01784 borders[0].first = 1; 01785 borders[0].second = 0; 01786 } 01787 // fix for bottom 01788 if (floorf(flowest) != flowest) 01789 { 01790 borders.back().first = 1; 01791 borders.back().second = 0; 01792 } 01793 } |
|
The same as compute borders, but pixel are seen as surfaces and not as points. Any pixel that is touched by the poly will be selected Definition at line 1344 of file polygon.cpp. References min, nlassert, NLMISC::ScanOuterEdgeLeft(), NLMISC::ScanOuterEdgeRight(), sint, TRasterVect, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.
01345 { 01346 // NB : this version is not much optimized, because of the min/max test 01347 // during rasterization. 01348 // TODO : optimize if needed ... 01349 01350 if (Vertices.empty()) 01351 { 01352 borders.clear(); 01353 minimumY = -1; 01354 return; 01355 } 01356 const CVector2f *first = &Vertices[0]; 01357 const CVector2f *last = first + Vertices.size(); 01358 01359 const CVector2f *curr = first, *next, *plowest ,*phighest; 01360 const CVector2f *pHighestRight, *pHighestRightNext, *pHighestLeft; 01361 const CVector2f *pPrevHighestLeft; 01362 double deltaXN, deltaYN, deltaXP, deltaYP; 01363 bool ccw; // true if CCW oriented 01364 sint polyHeight; 01365 sint highest, lowest; 01366 01367 float fright = curr->x; 01368 float fleft = curr->x; 01369 float fhighest = curr->y; 01370 float flowest = curr->y; 01371 plowest = phighest = curr; 01372 01373 // compute highest and lowest pos of the poly 01374 do 01375 { 01376 fright = std::max(fright, curr->x); 01377 fleft = std::min(fleft, curr->x); 01378 if (curr->y > flowest) 01379 { 01380 flowest = curr->y; 01381 plowest = curr; 01382 } 01383 if (curr->y < fhighest) 01384 { 01385 fhighest = curr->y; 01386 phighest = curr; 01387 } 01388 ++curr; 01389 } 01390 while (curr != last); 01391 01392 01393 highest = (sint) floorf(fhighest); 01394 lowest = (sint) floorf(flowest); 01395 01396 polyHeight = lowest - highest + 1; 01397 nlassert(polyHeight > 0); 01398 01399 // make room for rasters 01400 borders.resize(polyHeight); 01401 // fill with xmin / xman 01402 sint ileft = (sint) floorf(fleft); 01403 sint iright = (sint) ceilf(fright); 01404 for(TRasterVect::iterator it = borders.begin(); it != borders.end(); ++it) 01405 { 01406 it->second = ileft; 01407 it->first = iright; 01408 } 01409 01410 01411 minimumY = highest; 01412 pHighestRight = phighest; 01413 for (;;) 01414 { 01415 pHighestRightNext = pHighestRight + 1; 01416 if (pHighestRightNext == last) pHighestRightNext = first; 01417 if (pHighestRightNext->y != pHighestRight->y) break; 01418 pHighestRight = pHighestRightNext; 01419 } 01420 01421 pPrevHighestLeft = pHighestRight; 01422 pHighestLeft = pHighestRight; 01423 ++pHighestLeft; 01424 if (pHighestLeft == last) pHighestLeft = first; 01425 01426 while (pHighestLeft->y != fhighest) 01427 { 01428 pPrevHighestLeft = pHighestLeft; 01429 ++pHighestLeft; 01430 if (pHighestLeft == last) pHighestLeft = first; 01431 } 01432 01433 01434 // we need to get the orientation of the polygon 01435 // There are 2 case : flat, and non-flat top 01436 01437 // check for flat top 01438 if (pHighestLeft->x != pHighestRight->x) 01439 { 01440 // compare right and left side 01441 if (pHighestLeft->x > pHighestRight->x) 01442 { 01443 ccw = true; // the list is CCW oriented 01444 std::swap(pHighestLeft, pHighestRight); 01445 } 01446 else 01447 { 01448 ccw = false; // the list is CW oriented 01449 } 01450 } 01451 else 01452 { 01453 pHighestRightNext = pHighestRight + 1; 01454 if (pHighestRightNext == last) pHighestRightNext = first; 01455 deltaXN = pHighestRightNext->x - pHighestRight->x; 01456 deltaYN = pHighestRightNext->y - pHighestRight->y; 01457 deltaXP = pPrevHighestLeft->x - pHighestLeft->x; 01458 deltaYP = pPrevHighestLeft->y - pHighestLeft->y; 01459 if ((deltaXN * deltaYP - deltaYN * deltaXP) < 0) 01460 { 01461 ccw = true; 01462 std::swap(pHighestLeft, pHighestRight); 01463 } 01464 else 01465 { 01466 ccw = false; 01467 } 01468 } 01469 01470 if (!ccw) 01471 { 01472 // clock wise oriented list 01473 curr = pHighestRight; 01474 do 01475 { 01476 next = curr + 1; 01477 if (next == last) next = first; 01478 ScanOuterEdgeRight(&borders[0], curr->x, curr->y, next->x, next->y, minimumY); 01479 curr = next; 01480 } 01481 while (curr != plowest); 01482 do 01483 { 01484 next = curr + 1; 01485 if (next == last) next = first; 01486 ScanOuterEdgeLeft(&borders[0], next->x, next->y, curr->x, curr->y, minimumY); 01487 curr = next; 01488 } 01489 while (curr != pHighestLeft); 01490 } 01491 else 01492 { 01493 // ccw oriented 01494 curr = pHighestLeft; 01495 do 01496 { 01497 next = curr + 1; 01498 if (next == last) next = first; 01499 ScanOuterEdgeLeft(&borders[0], curr->x, curr->y, next->x, next->y, minimumY); 01500 curr = next; 01501 } 01502 while (curr != plowest); 01503 do 01504 { 01505 next = curr + 1; 01506 if (next == last) next = first; 01507 ScanOuterEdgeRight(&borders[0], next->x, next->y, curr->x, curr->y, minimumY); 01508 curr = next; 01509 } 01510 while (curr != pHighestRight); 01511 } 01512 } |
|
Check wether a point is contained by this poly. get the orientation of this poly contains the seg 2d equation don't check against a null segment get the line equation of the current segment contains the seg 2d equation Definition at line 1896 of file polygon.cpp. References getLineEquation(), getNonNullSeg(), getSegRef0(), getSegRef1(), nlassert, uint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. Referenced by intersect().
01897 { 01898 nlassert(Vertices.size() > 0); 01899 uint nonNullSegIndex; 01901 if (getNonNullSeg(nonNullSegIndex)) 01902 { 01903 float a0, b0, c0; 01904 getLineEquation(nonNullSegIndex, a0, b0, c0); 01905 01906 for (uint k = 0; k < Vertices.size(); ++k) 01907 { 01909 if ( (getSegRef0(k) - getSegRef1(k)).sqrnorm() == 0.f) continue; 01910 01912 float a, b, c; 01913 getLineEquation(k, a, b, c); 01914 01915 if (a * p.x + b * p.y + c < 0) return false; 01916 01917 } 01918 return true; 01919 } 01920 else // this poly is just a point 01921 { 01922 return p == Vertices[0]; 01923 } 01924 } |
|
get the best triplet of vector. e.g the triplet that has the best surface
Definition at line 967 of file polygon.cpp. References nlassert, uint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.
00968 { 00969 nlassert(Vertices.size() >= 3); 00970 uint i, j, k; 00971 float bestArea = 0.f; 00972 const uint numVerts = Vertices.size(); 00973 for (i = 0; i < numVerts; ++i) 00974 { 00975 for (j = 0; j < numVerts; ++j) 00976 { 00977 if (i != j) 00978 { 00979 for (k = 0; k < numVerts; ++k) 00980 { 00981 if (k != i && k != j) 00982 { 00983 CVector2f v0 = Vertices[j] - Vertices[i]; 00984 CVector2f v1 = Vertices[k] - Vertices[i]; 00985 float area = fabsf((CVector(v0.x, v0.y, 0) ^ CVector(v1.x, v1.y, 0)).norm()); 00986 if (area > bestArea) 00987 { 00988 bestArea = area; 00989 index0 = i; 00990 index1 = j; 00991 index2 = k; 00992 } 00993 } 00994 } 00995 } 00996 } 00997 } 00998 } |
|
Get a line equation of the seg starting at the given index.
Definition at line 1844 of file polygon.cpp. References getSegRef0(), getSegRef1(), index, nlassert, uint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. Referenced by contains(), and intersect().
01845 { 01846 nlassert(index < Vertices.size()); 01847 const CVector2f &v0 = getSegRef0(index); 01848 const CVector2f &v1 = getSegRef1(index); 01849 01850 NLMISC::CVector2f seg = v0 - v1; 01851 a = seg.y; 01852 b = - seg.x; 01853 c = - v0.x * a - v0.y * b; 01854 } |
|
Get the index of a segment of this poly that is a non null segment.
Definition at line 1810 of file polygon.cpp. References index, nlassert, sint, and uint. Referenced by contains(), and intersect().
01811 { 01812 nlassert(Vertices.size() > 0); 01813 float bestLength = 0.f; 01814 sint bestIndex = -1; 01815 for (uint k = 0; k < Vertices.size() - 1; ++k) 01816 { 01817 float norm2 = (Vertices[k + 1] - Vertices[k]).sqrnorm(); 01818 if ( norm2 > bestLength) 01819 { 01820 bestLength = norm2; 01821 bestIndex = (int) k; 01822 } 01823 } 01824 float norm2 = (Vertices[Vertices.size() - 1] - Vertices[0]).sqrnorm(); 01825 if ( norm2 > bestLength) 01826 { 01827 index = Vertices.size() - 1; 01828 return true; 01829 } 01830 01831 if (bestIndex != -1) 01832 { 01833 index = bestIndex; 01834 return true; 01835 } 01836 else 01837 { 01838 return false; 01839 } 01840 } |
|
Get ref to the first vertex that start at index.
Definition at line 197 of file polygon.h. References index, nlassert, and uint. Referenced by contains(), getLineEquation(), and intersect().
|
|
Definition at line 201 of file polygon.h. References index, nlassert, and uint. Referenced by contains(), getLineEquation(), and intersect().
|
|
Test wether this polygon intersect another convex polygon. Currently not optimized. get the orientation of this poly contains the seg 2d equation don't check against a null segment get the line equation of the current segment contains the seg 2d equation Definition at line 1857 of file polygon.cpp. References contains(), getLineEquation(), getNonNullSeg(), getSegRef0(), getSegRef1(), nlassert, sumDPAgainstLine(), uint, Vertices, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. Referenced by NL3D::CZoneLighter::computeTileFlagsForPositionTowardWater().
01858 { 01859 nlassert(other.Vertices.size() > 0); 01860 uint nonNullSegIndex; 01862 if (getNonNullSeg(nonNullSegIndex)) 01863 { 01864 float a0, b0, c0; 01865 getLineEquation(nonNullSegIndex, a0, b0, c0); 01866 float orient = sumDPAgainstLine(a0, b0, c0); 01867 01868 for (uint k = 0; k < Vertices.size(); ++k) 01869 { 01871 if ( (getSegRef0(k) - getSegRef1(k)).sqrnorm() == 0.f) continue; 01872 01874 float a, b, c; 01875 getLineEquation(k, a, b, c); 01876 uint l; 01877 for (l = 0; l < other.Vertices.size(); ++l) 01878 { 01879 const CVector2f &ov = other.Vertices[l]; 01880 if ( orient * (ov.x * a + ov.y * b +c) > 0.f) break; 01881 } 01882 if (l == other.Vertices.size()) // all point on the outside 01883 { 01884 return false; // outside 01885 } 01886 } 01887 return true; 01888 } 01889 else // this poly is just a point 01890 { 01891 return other.contains(Vertices[0]); 01892 } 01893 } |
|
Check wether this polygon is convex;.
Definition at line 798 of file polygon.cpp. References NLMISC::CPlane::make(), NLMISC::CVector::set(), uint, x, and y.
00799 { 00800 bool Front = true, Back = false; 00801 // we apply a dummy algo for now : check wether every vertex is in the same side 00802 // of every plane defined by a segment of this poly 00803 uint numVerts = Vertices.size(); 00804 if (numVerts < 3) return true; 00805 CVector segStart, segEnd; 00806 CPlane clipPlane; 00807 for (TVec2fVect::const_iterator it = Vertices.begin(); it != Vertices.end(); ++it) 00808 { 00809 segStart.set(it->x, it->y, 0); // segment start 00810 segEnd.set((it + 1)->x, (it + 1)->y, 0); // segment end 00811 float n = (segStart - segEnd).norm(); // segment norm 00812 if (n != 0) 00813 { 00814 clipPlane.make(segStart, segEnd, (n > 10 ? n : 10) * CVector::K + segStart); // make a plane, with this segment and the poly normal 00815 // check each other vertices against this plane 00816 for (TVec2fVect::const_iterator it2 = Vertices.begin(); it2 != Vertices.end(); ++it2) 00817 { 00818 if (it2 != it && it2 != (it + 1)) // the vertices must not be part of the test plane (because of imprecision) 00819 { 00820 00821 float dist = clipPlane * CVector(it2->x, it2-> y, 0); 00822 if (dist != 0) // midlle pos 00823 { 00824 if (dist > 0) Front = true; else Back = true; 00825 if (Front && Back) return false; // there are both front end back vertices -> failure 00826 } 00827 } 00828 } 00829 } 00830 } 00831 return true; 00832 } |
|
Serial this polygon.
Definition at line 959 of file polygon.cpp.
00960 { 00961 (void)f.serialVersion(0); 00962 f.serialCont(Vertices); 00963 } |
|
Sum the dot product of this poly vertices against a plane.
Definition at line 1797 of file polygon.cpp. References uint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y. Referenced by intersect().
|
|
Definition at line 132 of file polygon.h. References Vertices.
00132 { Vertices.swap(other.Vertices); } |
|