SEGMENTH CombinePolygonPieces(SEGMENTH *A1, SEGMENTH *B1, Boolean keepAinB, Boolean keepAnotinB, Boolean keepBinA, Boolean keepBnotinA) { long i, j, err, numSegsA, numSegsB, numSegsC = 0; WorldPoint m; SEGMENTH C = 0, A2 = 0, B2 = 0, *A = 0, *B = 0; err = 0; numSegsA = _GetHandleSize((Handle)*A1) / sizeof(Segment); numSegsB = _GetHandleSize((Handle)*B1) / sizeof(Segment); A2 = (SEGMENTH)_NewHandle(numSegsA * sizeof(Segment)); if (_MemError()) { TechError("CombinePolygonPieces()", "_NewHandle()", 0); goto done; } for (i = 0 ; i < numSegsA ; i++) INDEXH(A2, i) = INDEXH(*A1, i); A = &A2; B2 = (SEGMENTH)_NewHandle(numSegsB * sizeof(Segment)); if (_MemError()) { TechError("CombinePolygonPieces()", "_NewHandle()", 0); goto done; } for (i = 0 ; i < numSegsB ; i++) INDEXH(B2, i) = INDEXH(*B1, i); B = &B2; for (i = 0 ; i < numSegsA ; i++) for (j = 0 ; j < numSegsB ; j++) if (SegmentTouchesSegment(INDEXH(*A, i), INDEXH(*B, j)) && !SameSegmentEndPoints(INDEXH(*A, i), INDEXH(*B, j))) { m = PointOfIntersection(INDEXH(*A, i), INDEXH(*B, j)); if (err = InsertSegment(A, &numSegsA, i, m)) goto done; if (err = InsertSegment(B, &numSegsB, j, m)) goto done; } C = (SEGMENTH)_NewHandle(0); if (_MemError()) { TechError("CombinePolygonPieces()", "_NewHandle()", 0); goto done; } for (i = 0 ; i < numSegsA ; i++) { m = Midpoint(INDEXH(*A, i)); if ((keepAinB && PointInPolygon(m, *B, numSegsB, TRUE)) || (keepAnotinB && !PointInPolygon(m, *B, numSegsB, TRUE))) if (err = AddSegment(&C, &numSegsC, INDEXH(*A, i))) goto done; } for (j = 0 ; j < numSegsB ; j++) { m = Midpoint(INDEXH(*B, j)); if ((keepBinA && PointInPolygon(m, *A, numSegsA, TRUE)) || (keepBnotinA && !PointInPolygon(m, *A, numSegsA, TRUE))) if (err = AddSegment(&C, &numSegsC, INDEXH(*B, j))) goto done; } SortSegments(C, numSegsC); done: if (A2) DisposeHandle((Handle)A2); if (B2) DisposeHandle((Handle)B2); if (err && C) DisposeHandle((Handle)C); return err ? 0 : C; }
static ClippingInterPoint* CreateClippedPolygonData(const MeshPolygon* clippedPolygon, const MeshPolygon* clippingWindow) { const Point* pointListForClippedPolygon = GetPolygonPointList(clippedPolygon); const int pointCountForClippedPolygon = GetPolygonPointCount(clippedPolygon); ClippingInterPoint* pointChainForClippedPolygon = (ClippingInterPoint*)malloc(sizeof(ClippingInterPoint) * pointCountForClippedPolygon); for (int i = 0; i < pointCountForClippedPolygon; ++i) { int prevIndex = 0 == i ? pointCountForClippedPolygon - 1 : i - 1; int nextIndex = i + 1 == pointCountForClippedPolygon ? 0 : i + 1; pointChainForClippedPolygon[i].point = pointListForClippedPolygon[i]; pointChainForClippedPolygon[i].pointType = INTER_POINT_TYPE_CLIPPED_PYLIGON_POINT; pointChainForClippedPolygon[i].prev2ClippedPolygon = &pointChainForClippedPolygon[prevIndex]; pointChainForClippedPolygon[i].next2ClippedPolygon = &pointChainForClippedPolygon[nextIndex]; pointChainForClippedPolygon[i].prev2ClippingdWindow = NULL; pointChainForClippedPolygon[i].next2ClippingdWindow = NULL; pointChainForClippedPolygon[i].state = PROCESS_STATE_UNPROCESSED; pointChainForClippedPolygon[i].tValueForClippedPolygon = -999999.0f; pointChainForClippedPolygon[i].tValueForClippingWindow = -999999.0f; int checkReslt = PointInPolygon(clippingWindow, pointChainForClippedPolygon[i].point.x, pointChainForClippedPolygon[i].point.z); if (checkReslt >= 0) { pointChainForClippedPolygon[i].state = PROCESS_STATE_NO_NEED_PROCESS; } } return pointChainForClippedPolygon; }
bool SubSurface::Subtag( const vec3d & center ) { UpdatePolygonPnts(); // Update polygon vector for ( int p = 0; p < ( int )m_PolyPntsVec.size(); p++ ) { bool inPoly = PointInPolygon( vec2d( center.x(), center.y() ), m_PolyPntsVec[p] ); if ( inPoly && m_TestType() == vsp::INSIDE ) { return true; } else if ( inPoly && m_TestType() == vsp::OUTSIDE ) { return false; } } if ( m_TestType() == vsp::OUTSIDE ) { return true; } return false; }
bool A3DPlane::IntersectionInPolygon(const A3DLine& line, const A3DPoint *vertices, uint_t nVertices) const { A3DPoint pt1; bool success = false; if (Intersection(line, &pt1)) { success = PointInPolygon(pt1, vertices, nVertices); } return success; }
BOOL PolygonBuffer::AcceptBoundary(const OpsFloatExtent &boundaryExt, Orientation boundaryOrient, const OpsFloatPoint &boundaryVert, const OpsDoublePoint &interiorPt) const { // if the boundary has counter-clockwise orientation, then it is a potential // outer boundary - accept if the boundary extent fully contains the input // polygon object extent, or the boundary vertex does not lie within the // input polygon object if (boundaryOrient == CounterClockwise) { if (boundaryExt.Contains(&m_polyObjExt)) return TRUE; else { OpsDoublePoint vertex(boundaryVert.x, boundaryVert.y); return !PointInPolygon(vertex); } } // else the boundary has clockwise orientation, and may be a boundary of // a hole in the buffer zone - accept if the boundary vertex is not contain- // ed in the input polygon object, and the interior point is not within the // offset distance of any of the input polygons else { OpsDoublePoint vertex(boundaryVert.x, boundaryVert.y); if (PointInPolygon(vertex)) return FALSE; for (int i = 0, j = 0; i < m_nPolyObjects; i++) { if(PointWithinOffsetDist(&m_pVertices[j], m_pnPolyVerts[i], interiorPt)) return FALSE; j += m_pnPolyVerts[i]; } return TRUE; } } // end: AcceptBoundary()
bool IsCircleIntersectPolygon(Circle* circle, Polygon* polygon) { if (PointInPolygon(polygon, &circle->c)) return true; for (int i = 0, j = polygon->n - 1; i < polygon->n; j = i++) { Line line = { { polygon->v[i].x, polygon->v[i].y },{ polygon->v[j].x, polygon->v[j].y } }; if (IsCircleIntersectWhitLineSegment(circle, &line)) return true; } return false; }
bool Rectangle::Intersects(const Rectangle &other) { Vector2 points[4]; GetRotatedPosArray(points); Vector2 otherPoints[4]; other.GetRotatedPosArray(otherPoints); if(PointInPolygon(points[0], otherPoints, 4)) { return true; } if(PointInPolygon(points[1], otherPoints, 4)) { return true; } if(PointInPolygon(points[2], otherPoints, 4)) { return true; } if(PointInPolygon(points[3], otherPoints, 4)) { return true; } if(PointInPolygon(otherPoints[0], points, 4)) { return true; } if(PointInPolygon(otherPoints[1], points, 4)) { return true; } if(PointInPolygon(otherPoints[2], points, 4)) { return true; } if(PointInPolygon(otherPoints[3], points, 4)) { return true; } /** * NOTE: This should be fixed later, due to a special case where two rectangles of the same size are on the same * centered position, one of which is rotated at 45 degrees. Right now, this doesn't seem to work as it * should, so we need to figure out the bug in lineSegmentsIntersect() or re-implement the function entirely. */ /* if (mthLineSegmentsIntersect(points[0], points[1], otherPoints[0], otherPoints[1]) || mthLineSegmentsIntersect(points[1], points[2], otherPoints[0], otherPoints[1]) || mthLineSegmentsIntersect(points[2], points[3], otherPoints[0], otherPoints[1]) || mthLineSegmentsIntersect(points[3], points[0], otherPoints[0], otherPoints[1]) || mthLineSegmentsIntersect(points[0], points[1], otherPoints[1], otherPoints[2]) || mthLineSegmentsIntersect(points[1], points[2], otherPoints[1], otherPoints[2]) || mthLineSegmentsIntersect(points[2], points[3], otherPoints[1], otherPoints[2]) || mthLineSegmentsIntersect(points[3], points[0], otherPoints[1], otherPoints[2]) || mthLineSegmentsIntersect(points[0], points[1], otherPoints[2], otherPoints[3]) || mthLineSegmentsIntersect(points[1], points[2], otherPoints[2], otherPoints[3]) || mthLineSegmentsIntersect(points[2], points[3], otherPoints[2], otherPoints[3]) || mthLineSegmentsIntersect(points[3], points[0], otherPoints[2], otherPoints[3]) || mthLineSegmentsIntersect(points[0], points[1], otherPoints[3], otherPoints[0]) || mthLineSegmentsIntersect(points[1], points[2], otherPoints[3], otherPoints[0]) || mthLineSegmentsIntersect(points[2], points[3], otherPoints[3], otherPoints[0]) || mthLineSegmentsIntersect(points[3], points[0], otherPoints[3], otherPoints[0]) ) { return true; } */ return false; }
int main() { int runs; scanf("%d", &runs); while (runs--) { int n; scanf("%d", &n); Point tp; tp.x = 0, tp.y = 0; for (int i = 0, x, y; i < n; ++i) { scanf("%d%d", &x, &y); pt[i].x = x + tp.x, pt[i].y = y + tp.y; tp = pt[i]; } printf("%d\n", PointInPolygon(n, pt)); } return 0; }
IplImage* ImageAnalysis::maskImage(IplImage* rf,int i) { for( int y=0; y<rf->height; y++ ) { uchar* ptr = (uchar*) (rf->imageData + y * rf->widthStep); for( int x=0; x<rf->width; x++ ) { if(!PointInPolygon(cvPoint(x,y),i)) { ptr[3*x] = 0; // B - синий ptr[3*x+1] = 0; // G - зелёный ptr[3*x+2] = 0; // R - красный } } } return rf; }
Boolean PointInPoly (LongPoint *theLPoint, PolyObjectHdl mapPolyHdl) { Boolean bInPoly = false; SegmentsHdl thisSegHdl = nil; long numSegs; thisSegHdl = RgnToSegment (mapPolyHdl); if (thisSegHdl) { WorldPoint wp; wp.pLat = theLPoint -> v; wp.pLong = theLPoint -> h; numSegs = _GetHandleSize ((Handle) thisSegHdl) / sizeof (Segment); bInPoly = PointInPolygon (wp, thisSegHdl, numSegs, false); DisposeHandle ((Handle) thisSegHdl); } return bInPoly; }
IntersectResult PolygonContainer<TYPE>::QueryPointInPolygon(Node* node) { QuadTree* tree = this; while(tree) { if(tree == 0) continue; QuadObjects objects = tree->GetObjects(); QuadObjectIterator it = objects.begin(); for(;it != objects.end();it++) { QuadObject* quad = *it; TYPE* poly = (TYPE*)quad; IntersectResult ret = PointInPolygon(node, poly); if (ret != IR_SEPERATE) return ret; } Geometry::TREE_LOCATION location = tree->GetLocation(node->X(), node->Y()); if(location == Geometry::TL_CHILD0) { tree = tree->SubNode(0); } else if(location == Geometry::TL_CHILD1) { tree = tree->SubNode(1); } else if(location == Geometry::TL_CHILD2) { tree = tree->SubNode(2); } else if(location == Geometry::TL_CHILD3) { tree = tree->SubNode(3); } else { break; } } return IR_SEPERATE; }
void ControlCityThemeExample::FindThemeByPointInPolygon() { Eegeo::Space::LatLong osaka = Eegeo::Space::LatLong::FromDegrees(34.700131,135.478884); Eegeo::v2 osakav2(static_cast<float>(osaka.GetLatitudeInDegrees()), static_cast<float>(osaka.GetLongitudeInDegrees())); // enumerate all of the themes in the theme repository int numberOfThemes = m_themeRepository.GetNumberOfThemes(); for (int i=0; i<numberOfThemes; ++i) { const Eegeo::Resources::CityThemes::CityThemeData& themeData = m_themeRepository.GetCityThemeAt(i); if (themeData.PolygonBounds.size() > 0) // there are points in the bounding polygon { std::vector<Eegeo::v2> polygon; VectorLatLonToV2(themeData.PolygonBounds, polygon); if (PointInPolygon(polygon, osakav2)) { EXAMPLE_LOG("This theme contains the Osaka point: %s\n", themeData.Name.c_str()); return; } } } EXAMPLE_LOG("No theme found that contains the Osaka point\n"); }
/* shade a secret (S) or damage (D) Sector w/o their inner Sectors */ void ShadeSector( BCINT sector, char type) { BCINT lines[ MAXLNS], end = 0; BCINT l, outer, next; if (! BuildPolygons( lines, sector, &end)) { printf( "[%s sector %d has too many lines for shading.]\n", ( type == 'S' ? "Secret" : "Damage" ), sector); return; } /* shade the secret/damage Sector */ outer = l = 0; while (l < end) { /* shade the outer polygon */ ShadePolygon( lines, outer, type, &next); l = next + 1; while (l < end) { next = (lines[l] > 0) ? LineDefs[ lines[l]-1].start : LineDefs[-lines[l]-1].end; /* check for disjoint polygon */ if (! PointInPolygon( lines, outer, Vertexes[ next].x, Vertexes[ next].y, &next)) { outer = l; break; /* while */ } /* un-shade inner polygon(s) */ ShadePolygon( lines, l, 'W', &next); l = next + 1; } } }
int main() { // expected (-5,2)/(5,-2)/(-5,2)/(5,2)/(5,2) (7.5,3) (2.5,1) cerr << RotateCCW90(PT(2,5)) << endl; cerr << RotateCW90(PT(2,5)) << endl; cerr << RotateCCW(PT(2,5),M_PI/2) << endl; cerr << ProjectPointLine(PT(-5,-2), PT(10,4), PT(3,7)) << endl; cerr << ProjectPointSegment(PT(-5,-2), PT(10,4), PT(3,7)) << " " << ProjectPointSegment(PT(7.5,3), PT(10,4), PT(3,7)) << " " << ProjectPointSegment(PT(-5,-2), PT(2.5,1), PT(3,7)) << endl; // expected 6.78903/1 0 1/0 0 1/1 1 1 0/(1,2)/(1,1) cerr << DistancePointPlane(4,-4,3,2,-2,5,-8) << endl; cerr << LinesParallel(PT(1,1), PT(3,5), PT(2,1), PT(4,5)) << " " << LinesParallel(PT(1,1), PT(3,5), PT(2,0), PT(4,5)) << " " << LinesParallel(PT(1,1), PT(3,5), PT(5,9), PT(7,13)) << endl; cerr << LinesCollinear(PT(1,1), PT(3,5), PT(2,1), PT(4,5)) << " " << LinesCollinear(PT(1,1), PT(3,5), PT(2,0), PT(4,5)) << " " << LinesCollinear(PT(1,1), PT(3,5), PT(5,9), PT(7,13)) << endl; cerr << SegmentsIntersect(PT(0,0), PT(2,4), PT(3,1), PT(-1,3)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(4,3), PT(0,5)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(2,-1), PT(-2,1)) << " " << SegmentsIntersect(PT(0,0), PT(2,4), PT(5,5), PT(1,7)) << endl; cerr << ComputeLineIntersection(PT(0,0),PT(2,4),PT(3,1),PT(-1,3)) << endl; cerr << ComputeCircleCenter(PT(-3,4), PT(6,1), PT(4,5)) << endl; vector<PT> v; v.push_back(PT(0,0)); v.push_back(PT(5,0)); v.push_back(PT(5,5)); v.push_back(PT(0,5)); // expected: 1 1 1 0 0 cerr << PointInPolygon(v, PT(2,2)) << " " << PointInPolygon(v, PT(2,0)) << " " << PointInPolygon(v, PT(0,2)) << " " << PointInPolygon(v, PT(5,2)) << " " << PointInPolygon(v, PT(2,5)) << endl; // expected: 0 1 1 1 1 cerr << PointOnPolygon(v, PT(2,2)) << " " << PointOnPolygon(v, PT(2,0)) << " " << PointOnPolygon(v, PT(0,2)) << " " << PointOnPolygon(v, PT(5,2)) << " " << PointOnPolygon(v, PT(2,5)) << endl; // expected: (1,6)/(5,4) (4,5)//(4,5) (5,4)//(4,5) (5,4) vector<PT> u = CircleLineIntersection(PT(0,6), PT(2,6), PT(1,1), 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleLineIntersection(PT(0,9), PT(9,0), PT(1,1), 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(10,10), 5, 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(8,8), 5, 5); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(4.5,4.5), 10, sqrt(2.0)/2.0); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; u = CircleCircleIntersection(PT(1,1), PT(4.5,4.5), 5, sqrt(2.0)/2.0); for (int i = 0; i < u.size(); i++) cerr << u[i] << " "; cerr << endl; // area should be 5.0; centroid should be (1.1666666, 1.166666) PT pa[] = {PT(0,0), PT(5,0), PT(1,1), PT(0,5)}; vector<PT> p(pa, pa+4); PT c = ComputeCentroid(p); cerr << "Area: " << ComputeArea(p) << endl; cerr << "Centroid: " << c << endl; }
bool Rectangle::Contains(const Vector2 &point) { Vector2 verts[4]; GetRotatedPosArray(verts); return PointInPolygon(point, verts, 4); }
int ConvexPolygonClipping(const MeshPolygon* clippedPolygon, const MeshPolygon* clippingWindow, Queue* queue) { if(NULL == clippedPolygon || NULL == clippingWindow || NULL == queue) { return WRONG_PARAM; } int allPointCountForClipping = 0; const Point* pointListForClipingWindow = GetPolygonPointList(clippingWindow); const int pointCountForClippingWindow = GetPolygonPointCount(clippingWindow); allPointCountForClipping += pointCountForClippingWindow; int clipingWindowPointInClippedWindowCount[3] = {0}; for (int i = 0; i < pointCountForClippingWindow; ++i) { int checkResult = PointInPolygon(clippedPolygon, pointListForClipingWindow[i].x, pointListForClipingWindow[i].z); ++clipingWindowPointInClippedWindowCount[checkResult + 1]; } //裁剪多边形的顶点都位于被裁剪多边形的内部或者边上 //目前无法裁剪这种情况 if (0 == clipingWindowPointInClippedWindowCount[0]) { return CLIPPING_WINDOW_ALL_IN_CLIPPED_POLYGON; } const Point* pointListForClippedPolygon = GetPolygonPointList(clippedPolygon); const int pointCountForClippedPolygon = GetPolygonPointCount(clippedPolygon); int clippedPolygonointInClippedWindowCount[3] = {0}; for (int i = 0; i < pointCountForClippedPolygon; ++i) { int checkResult = PointInPolygon(clippingWindow, pointListForClippedPolygon[i].x, pointListForClippedPolygon[i].z); ++clippedPolygonointInClippedWindowCount[checkResult + 1]; } allPointCountForClipping += pointCountForClippedPolygon; //被裁剪的多边形的顶点全部为与裁剪多边形内或边上 //不需要参见 if (0 == clippedPolygonointInClippedWindowCount[0]) { return ALL_POINT_IN_CLIPPING_WINDOW; } //两多边形不相交 不需要裁剪 if (0 == clipingWindowPointInClippedWindowCount[2] && 0 == clippedPolygonointInClippedWindowCount[2]) { return NOT_NEED_CLIPPING; } ClippingInterPoint* pointChainForClippingWindow = CreateClippingWindowData(clippedPolygon, clippingWindow); ClippingInterPoint* pointChainForClippedPolygon = CreateClippedPolygonData(clippedPolygon, clippingWindow); //查找交点并将交点插入正确的位置 const Vector* const pNormalOfClippedPolygon = GetPolygonNormal(clippedPolygon); Rect checkRect; for (int indexOfClippingWindow = 0; indexOfClippingWindow < pointCountForClippingWindow; ++indexOfClippingWindow) { int nextIndexOfClippingWindow = indexOfClippingWindow + 1 == pointCountForClippingWindow ? 0 : indexOfClippingWindow + 1; for (int indexOfclippedPolygon = 0; indexOfclippedPolygon < pointCountForClippedPolygon; ++indexOfclippedPolygon) { int nextIndexOfClippedPolygon = indexOfclippedPolygon + 1 == pointCountForClippedPolygon ? 0 : indexOfclippedPolygon + 1; ClippingInterPoint* const pBeginPointOfClippinWindow = &pointChainForClippingWindow[indexOfClippingWindow]; ClippingInterPoint* const pEndPointOfClippinWindow = &pointChainForClippingWindow[nextIndexOfClippingWindow]; ClippingInterPoint* const pBeginPointOfClippedPolygon = &pointChainForClippedPolygon[indexOfclippedPolygon]; ClippingInterPoint* const pEndPointOfClippedPolygon = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; Vector toBeginPoint = {pBeginPointOfClippinWindow->point.x - pBeginPointOfClippedPolygon->point.x, 0.0f, pBeginPointOfClippinWindow->point.z - pBeginPointOfClippedPolygon->point.z}; Vector toEndPoint = {pEndPointOfClippinWindow->point.x - pBeginPointOfClippedPolygon->point.x, 0.0f, pEndPointOfClippinWindow->point.z - pBeginPointOfClippedPolygon->point.z}; float cosofToBeginPoint = VectorDotProduct(&toBeginPoint, &pNormalOfClippedPolygon[indexOfclippedPolygon]); float cosofToEndPoint = VectorDotProduct(&toEndPoint, &pNormalOfClippedPolygon[indexOfclippedPolygon]); bool beginPointIsSpecial = (FloatEqualZero(cosofToBeginPoint) && cosofToEndPoint > 0.0f); bool endPointIsSpecial = (FloatEqualZero(cosofToEndPoint) && cosofToBeginPoint> 0.0f); if (beginPointIsSpecial || endPointIsSpecial) { //特殊点,即交点在被裁减的多边形的边上,且同在内侧 ClippingInterPoint* pTempPoint = beginPointIsSpecial ? pBeginPointOfClippinWindow : pEndPointOfClippinWindow; pTempPoint->pointType = INTER_POINT_TYPE_CLIPPING_WINDOW_POINT_AN_INSERCTION_POINT; ClippingInterPoint* pCurrentPositon = &pointChainForClippedPolygon[indexOfclippedPolygon]; ClippingInterPoint* pNextPosition = pCurrentPositon->next2ClippedPolygon; ClippingInterPoint* pEndPosition = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; pTempPoint->tValueForClippedPolygon = GetTValue(&pBeginPointOfClippedPolygon->point, &pEndPointOfClippedPolygon->point, &pTempPoint->point); while (true) { if( pTempPoint->tValueForClippedPolygon < pCurrentPositon->tValueForClippedPolygon) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippedPolygon; pLastPosition->next2ClippedPolygon = pTempPoint; pCurrentPositon->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pLastPosition; pTempPoint->next2ClippedPolygon = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippedPolygon = pTempPoint; pNextPosition->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pCurrentPositon; pTempPoint->next2ClippedPolygon = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippedPolygon; } continue; } if (FloatEqualZero(cosofToBeginPoint) && cosofToEndPoint < 0.0f) { //特殊点,即交点在被裁减的多边形的边上,且同在外侧 //直接抛弃,不处理 continue; } if (FloatEqualZero(cosofToEndPoint) && cosofToBeginPoint < 0.0f) { //特殊点,即交点在被裁减的多边形的边上,且同在外侧 //直接抛弃,不处理 continue; } //如果两点在边的同一侧,即没有交点,直接跳过 if (cosofToBeginPoint > 0.0f && cosofToEndPoint > 0.0f) { continue; } if (cosofToBeginPoint < 0.0f && cosofToEndPoint < 0.0f) { continue; } //如果有交点,则求交点并将交点插入正确的位置 //两相交线段求交点 //从而可以求出p的坐标 具体算法可以参考图形学算法 float tValue =cosofToBeginPoint; tValue /= (cosofToBeginPoint - cosofToEndPoint); float insertionX = pBeginPointOfClippinWindow->point.x + tValue * (pEndPointOfClippinWindow->point.x - pBeginPointOfClippinWindow->point.x); float insertionZ = pBeginPointOfClippinWindow->point.z + tValue * (pEndPointOfClippinWindow->point.z - pBeginPointOfClippinWindow->point.z); //检查点是否在线段的延长线上 Point point = {insertionX, insertionZ}; Point a = pBeginPointOfClippedPolygon->point; Point b = pEndPointOfClippedPolygon->point; MakeRectByPoint(&checkRect, &a, &b); if(true != InRect(&checkRect, &point)) { continue; } a = pBeginPointOfClippinWindow->point; b = pEndPointOfClippinWindow->point; MakeRectByPoint(&checkRect, &a, &b); if(true != InRect(&checkRect, &point)) { continue; } ClippingInterPoint* pTempPoint = (ClippingInterPoint*)malloc(sizeof(ClippingInterPoint)); ++allPointCountForClipping; pTempPoint->point = point; pTempPoint->tValueForClippingWindow = tValue; pTempPoint->tValueForClippedPolygon = GetTValue(&pBeginPointOfClippedPolygon->point, &pEndPointOfClippedPolygon->point, &point); //通过遍历链表查找正确的位置插入生成点 ClippingInterPoint* pCurrentPositon = &pointChainForClippingWindow[indexOfClippingWindow]; ClippingInterPoint* pNextPosition = pCurrentPositon->next2ClippingdWindow; ClippingInterPoint* pEndPosition = &pointChainForClippingWindow[nextIndexOfClippingWindow]; bool pointIsAdd = false; while(true) { if (IsSamePoint(&pTempPoint->point, &pCurrentPositon->point)) { //检查该点以否已经添加,如果已经添加则退出循环 //防止重复添加导致在后面在裁剪的时候死循环 pointIsAdd = true; break; } if( pTempPoint->tValueForClippingWindow < pCurrentPositon->tValueForClippingWindow) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippingdWindow; pLastPosition->next2ClippingdWindow = pTempPoint; pCurrentPositon->prev2ClippingdWindow = pTempPoint; pTempPoint->prev2ClippingdWindow = pLastPosition; pTempPoint->next2ClippingdWindow = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippingdWindow = pTempPoint; pNextPosition->prev2ClippingdWindow = pTempPoint; pTempPoint->prev2ClippingdWindow = pCurrentPositon; pTempPoint->next2ClippingdWindow = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippingdWindow; } if (true == pointIsAdd) { free(pTempPoint); continue; } //通过遍历链表查找正确的位置插入生成点 pCurrentPositon = &pointChainForClippedPolygon[indexOfclippedPolygon]; pNextPosition = pCurrentPositon->next2ClippedPolygon; pEndPosition = &pointChainForClippedPolygon[nextIndexOfClippedPolygon]; while (true) { if( pTempPoint->tValueForClippedPolygon < pCurrentPositon->tValueForClippedPolygon) { ClippingInterPoint* pLastPosition = pCurrentPositon->prev2ClippedPolygon; pLastPosition->next2ClippedPolygon = pTempPoint; pCurrentPositon->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pLastPosition; pTempPoint->next2ClippedPolygon = pCurrentPositon; break; } else if (pEndPosition == pNextPosition) { pCurrentPositon->next2ClippedPolygon = pTempPoint; pNextPosition->prev2ClippedPolygon = pTempPoint; pTempPoint->prev2ClippedPolygon = pCurrentPositon; pTempPoint->next2ClippedPolygon = pNextPosition; break; } pCurrentPositon = pNextPosition; pNextPosition = pCurrentPositon->next2ClippedPolygon; } if (cosofToBeginPoint < 0.0f && cosofToEndPoint > 0.0f) { pTempPoint->pointType = INTER_POINT_TYPE_INTERSECTION_POINT_FOR_IN; } else if(cosofToBeginPoint > 0.0f && cosofToEndPoint < 0.0f) { pTempPoint->pointType = INTER_POINT_TYPE_INTERSECTION_POINT_FOR_OUT; } else { assert(0); } } } //完成链表构建 //开始生成convex polygon //首先检查是否有足够的空间容纳结果 int* bufferForPolygonConverCount = (int*)malloc(sizeof(int*) * allPointCountForClipping); GenerateConvexPolygon(pointChainForClippedPolygon, pointCountForClippedPolygon, NULL, bufferForPolygonConverCount, allPointCountForClipping); //完成链表构建 //开始生成convex polygon for (int i = 0; i < pointCountForClippedPolygon; ++i) { pointChainForClippedPolygon[i].state = PROCESS_STATE_UNPROCESSED; int checkResult = PointInPolygon(clippingWindow, pointChainForClippedPolygon[i].point.x, pointChainForClippedPolygon[i].point.z); if (checkResult >= 0) { pointChainForClippedPolygon[i].state = PROCESS_STATE_NO_NEED_PROCESS; } } GenerateConvexPolygon(pointChainForClippedPolygon, pointCountForClippedPolygon, queue, bufferForPolygonConverCount, allPointCountForClipping); //释放分配的内存 ClippingInterPoint* pCurrent = &pointChainForClippedPolygon[0]; ClippingInterPoint* pNext = pCurrent->next2ClippedPolygon; while (pNext != &pointChainForClippedPolygon[0]) { if (INTER_POINT_TYPE_INTERSECTION_POINT_FOR_IN == pNext->pointType || INTER_POINT_TYPE_INTERSECTION_POINT_FOR_OUT == pNext->pointType) { pCurrent = pNext; pNext = pNext->next2ClippedPolygon; free(pCurrent); } else { pNext = pNext->next2ClippedPolygon; } } Queue* checkQueue = CreateQueue(GetDataCountFromQueue(queue)); while (MeshPolygon* checkPolygon = (MeshPolygon*)PopDataFromQueue(queue)) { if (true != IsSamePolygon(checkPolygon, clippedPolygon)) { PushDataToQueue(checkQueue, (void*)checkPolygon); } } ShiftQueueData(queue, checkQueue); ReleaseQueue(checkQueue); free(bufferForPolygonConverCount); free(pointChainForClippedPolygon); free(pointChainForClippingWindow); return 0; }
BOOL BCGPIntersectTriangle2D(CBCGPPoint arPoly1[], CBCGPPoint arPoly2[], CBCGPPoint arPolyRes[], int& nResCount) { int nPoly1Size = 3; int nPoly2Size = 3; nResCount = 0; int i = 0; int j = 0; // 1. find all points from arPoly1F in arPoly2F int nSize1 = 0; for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& pt = arPoly1[i]; if (PointInPolygon (arPoly2, pt)) { if (AddPointInPolygon(arPolyRes, pt, nResCount)) { nSize1++; } } } // all points in arPoly2F if (nSize1 == nPoly1Size) { return TRUE; } // 2. find all points from arPoly2F in arPoly1F int nSize2 = 0; for (i = 0; i < nPoly2Size; i++) { const CBCGPPoint& pt = arPoly2[i]; if (PointInPolygon (arPoly1, pt)) { if (AddPointInPolygon(arPolyRes, pt, nResCount)) { nSize2++; } } } // all points in arPoly1F if (nSize1 == 0 && nSize2 == nPoly2Size) { return TRUE; } // 3. find all intersection points arPoly1F and arPoly2F for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& ptStart1 = arPoly1[i]; const CBCGPPoint& ptEnd1 = arPoly1[(i + 1) % nPoly1Size]; for (j = 0; j < nPoly2Size; j++) { const CBCGPPoint& ptStart2 = arPoly2[j]; const CBCGPPoint& ptEnd2 = arPoly2[(j + 1) % nPoly2Size]; if (bcgp_classify_point2D(ptStart1, ptEnd1, ptStart2) != bcgp_classify_point2D(ptStart1, ptEnd1, ptEnd2)) { CBCGPPoint pt; if (BCGPIntersectPoints2D (ptStart1, ptEnd1, ptStart2, ptEnd2, pt)) { AddPointInPolygon(arPolyRes, pt, nResCount); } } } } if (nResCount < 3) { nResCount = 0; return FALSE; } return TRUE; }
/* find a Teleport Exit inside the given Sector */ BCINT FindTeleExit( BCINT sector) { BCINT lines[ MAXLNS], end = 0; BCINT m, l, outer, next; Bool outside; if (! BuildPolygons( lines, sector, &end)) { printf( "[Sector %d has too many lines to find teleport exit in.]\n", sector); return NumThings; } /* find all teleport exits */ for (m = 0; m < NumThings; m++) if (Things[ m].type == THING_TELEPORT) { /* check all disjoint outer polygons */ outer = l = 0; while (l < end) /* check if Thing inside this outer polygon */ if (PointInPolygon( lines, outer, Things[ m].xpos, Things[ m].ypos, &next)) { outside = TRUE; /* check if Thing outside all inner polygons */ l = next + 1; while (l < end) { next = (lines[l] > 0) ? LineDefs[ lines[l]-1].start : LineDefs[-lines[l]-1].end; /* check for disjoint polygon */ if (! PointInPolygon( lines, outer, Vertexes[ next].x, Vertexes[ next].y, &next)) { outer = l; break; /* while */ } if (PointInPolygon( lines, l, Things[ m].xpos, Things[ m].ypos, &next)) outside = FALSE; l = next + 1; } if (outside) return m; } else /* skip inner polygons */ { l = next + 1; while (l < end) { next = (lines[l] > 0) ? LineDefs[ lines[l]-1].start : LineDefs[-lines[l]-1].end; /* check for disjoint polygon */ if (! PointInPolygon( lines, outer, Vertexes[ next].x, Vertexes[ next].y, &next)) { outer = l; break; /* while */ } outside = PointInPolygon( lines, l, Things[ m].xpos, Things[ m].ypos, &next); l = next + 1; } } } return NumThings; }
BOOL BCGPCalculateIntersectPoint(const CBCGPPointsArray& arPoly1, const CBCGPPointsArray& arPoly2, CBCGPPoint& ptIntersect) { int nPoly1Size = (int)arPoly1.GetSize(); int nPoly2Size = (int)arPoly2.GetSize(); if (nPoly1Size == 0 || nPoly2Size == 0) { return FALSE; } const CBCGPPoint* pData1 = arPoly1.GetData (); const CBCGPPoint* pData2 = arPoly2.GetData (); CBCGPPointsArray arPolyRes; arPolyRes.SetSize (0, nPoly1Size + nPoly2Size); int i = 0; int j = 0; // 1. find all points from arPoly1F in arPoly2F int nSize1 = 0; for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& pt = pData1[i]; if (PointInPolygon (arPoly2, pt)) { if (AddPointInPolygon(arPolyRes, pt)) { nSize1++; } } } // all points in arPoly2F if (nSize1 != nPoly1Size) { // 2. find all points from arPoly2F in arPoly1F int nSize2 = 0; for (i = 0; i < nPoly2Size; i++) { const CBCGPPoint& pt = pData2[i]; if (PointInPolygon (arPoly1, pt)) { if (AddPointInPolygon(arPolyRes, pt)) { nSize2++; } } } // all points in arPoly1F if (nSize1 != 0 || nSize2 != nPoly2Size) { // 3. find all intersection points arPoly1F and arPoly2F for (i = 0; i < nPoly1Size; i++) { const CBCGPPoint& ptStart1 = pData1[i]; const CBCGPPoint& ptEnd1 = pData1[(i + 1) % nPoly1Size]; for (j = 0; j < nPoly2Size; j++) { const CBCGPPoint& ptStart2 = pData2[j]; const CBCGPPoint& ptEnd2 = pData2[(j + 1) % nPoly2Size]; if (bcgp_classify_point2D(ptStart1, ptEnd1, ptStart2) != bcgp_classify_point2D(ptStart1, ptEnd1, ptEnd2)) { CBCGPPoint pt; if (BCGPIntersectPoints2D (ptStart1, ptEnd1, ptStart2, ptEnd2, pt)) { AddPointInPolygon(arPolyRes, pt); } } } } } } int nSize = (int)arPolyRes.GetSize(); if (nSize < 2) { return FALSE; } ptIntersect.x = 0.0; ptIntersect.y = 0.0; for (i = 0; i < nSize; i++) { ptIntersect += arPolyRes[i]; } ptIntersect /= nSize; return TRUE; }
void ConvertOutlineToTriangles(Vertices &ioOutline,const QuickVec<int> &inSubPolys) { // Order polygons ... int subs = inSubPolys.size(); if (subs<1) return; QuickVec<SubInfo> subInfo; QuickVec<EdgePoint> edges(ioOutline.size()); int index = 0; int groupId = 0; for(int sub=0;sub<subs;sub++) { SubInfo info; info.p0 = sub>0?inSubPolys[sub-1]:0; info.size = inSubPolys[sub] - info.p0; if (ioOutline[info.p0] == ioOutline[info.p0+info.size-1]) info.size--; if (info.size>2) { UserPoint *p = &ioOutline[info.p0]; double area = 0.0; for(int i=2;i<info.size;i++) { UserPoint v_prev = p[i-1] - p[0]; UserPoint v_next = p[i] - p[0]; area += v_prev.Cross(v_next); } bool reverse = area < 0; int parent = -1; for(int prev=subInfo.size()-1; prev>=0 && parent==-1; prev--) { if (subInfo[prev].contains(p[0])) { int prev_p0 = subInfo[prev].p0; int prev_size = subInfo[prev].size; int inside = PIP_MAYBE; for(int test_point = 0; test_point<info.size && inside==PIP_MAYBE; test_point++) { inside = PointInPolygon( p[test_point], &ioOutline[prev_p0], prev_size); if (inside==PIP_YES) parent = prev; } } } if (parent==-1 || subInfo[parent].is_internal ) { info.group = groupId++; info.is_internal = false; } else { info.group = subInfo[parent].group; info.is_internal = true; } info.first = &edges[index]; AddSubPoly(info.first,p,info.size,reverse!=info.is_internal); if (sub<subs-1) info.calcExtent(); index += info.size; subInfo.push_back(info); } } Vertices triangles; for(int group=0;group<groupId;group++) { int first = -1; int size = 0; for(int sub=0;sub<subInfo.size();sub++) { SubInfo &info = subInfo[sub]; if (info.group==group) { if (first<0) { first = sub; size = info.size; } else { LinkSubPolys(subInfo[first].first,info.first, info.link); size += info.size + 2; } } } ConvertOutlineToTriangles(subInfo[first].first, size,triangles); } ioOutline.swap(triangles); }