// Use this for initialization void Start() { polygonTweens = gameObject.AddComponent <PolygonTweens>(); polygonUtil = gameObject.AddComponent <PolygonUtil>(); polygonMeshBuilder = gameObject.AddComponent <PolygonMeshBuilder>(); polygonMeshBuilder.PolygonProperties = polygonProperties; polygonCoreLogic = gameObject.AddComponent <PolygonCoreLogic>(); polygonCoreLogic.PolygonUtil = polygonUtil; polygonCoreLogic.PolygonMeshBuilder = polygonMeshBuilder; polygonCoreLogic.PolygonProperties = polygonProperties; PolygonCoreLogic.PolyStarted += OnPolyStarted; PolygonCoreLogic.PolyEnded += OnPolyEnded; PolygonCoreLogic.PolyExecuted += OnPolyExecuted; polygonEnemyDetection = gameObject.AddComponent <PolygonEnemyDetection>(); polygonEnemyDetection.PolygonCoreLogic = polygonCoreLogic; polygonEnemyDetection.PolygonProperties = polygonProperties; hintArrowSystem = gameObject.AddComponent <HintArrowSystem>(); hintArrowSystem.PolygonProperties = polygonProperties; hintArrowSystem.PolygonCoreLogic = polygonCoreLogic; killedEnemyDisplayer = gameObject.AddComponent <KilledEnemyDisplayer>(); killedEnemyDisplayer.PolygonProperties = polygonProperties; }
public bool ContainsPoint(Vector2 point) { s_PolygonHolder[0] = p0; s_PolygonHolder[1] = p1; s_PolygonHolder[2] = p2; s_PolygonHolder[3] = p3; return(PolygonUtil.PointInPolygon(point, s_PolygonHolder, 4)); }
private bool IsPointInsideContour(Point2D p) { if (PolygonUtil.PointInPolygon2D(this, p)) { return(_holes.All(c => !c.IsPointInsideContour(p))); } return(false); }
public void Test_Intersect() { var pnts = new List <Vec2> { new Vec2(0.0, 0.0), new Vec2(1.0, 0.0), new Vec2(1.0, 1.0), new Vec2(0.5, 0.5), new Vec2(0.0, 1.0) }; var tol = 1e-10; Assert.Equal(PolygonPointRes.Vetex, PolygonUtil.CrossTest(new Vec2(0.0, 0.0), pnts, tol)); Assert.Equal(PolygonPointRes.Edge, PolygonUtil.CrossTest(new Vec2(0.1, 0.0), pnts, tol)); Assert.Equal(PolygonPointRes.Outside, PolygonUtil.CrossTest(new Vec2(0.5, 0.6), pnts, tol)); Assert.Equal(PolygonPointRes.Outside, PolygonUtil.CrossTest(new Vec2(0.5, 0.500001), pnts, tol)); Assert.Equal(PolygonPointRes.Inside, PolygonUtil.CrossTest(new Vec2(0.5, 0.499999), pnts, tol)); Assert.Equal(PolygonPointRes.Outside, PolygonUtil.CrossTest(new Vec2(1.5, 0.5), pnts, tol)); }
public bool IsPointInsideContour(Point2D p) { if (PolygonUtil.PointInPolygon2D(this, p)) { foreach (Contour c in mHoles) { if (c.IsPointInsideContour(p)) { return(false); } } return(true); } return(false); }
public static void InitializeHoles(List <Contour> holes, ITriangulatable parent, ConstrainedPointSet cps) { int numHoles = holes.Count; int holeIdx = 0; // pass 1 - remove duplicates while (holeIdx < numHoles) { int hole2Idx = holeIdx + 1; while (hole2Idx < numHoles) { bool bSamePolygon = PolygonUtil.PolygonsAreSame2D(holes[holeIdx], holes[hole2Idx]); if (bSamePolygon) { // remove one of them holes.RemoveAt(hole2Idx); --numHoles; } else { ++hole2Idx; } } ++holeIdx; } // pass 2: Intersections and Containment holeIdx = 0; while (holeIdx < numHoles) { bool bIncrementHoleIdx = true; int hole2Idx = holeIdx + 1; while (hole2Idx < numHoles) { if (PolygonUtil.PolygonContainsPolygon(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds, false)) { holes[holeIdx].AddHole(holes[hole2Idx]); holes.RemoveAt(hole2Idx); --numHoles; } else if (PolygonUtil.PolygonContainsPolygon(holes[hole2Idx], holes[hole2Idx].Bounds, holes[holeIdx], holes[holeIdx].Bounds, false)) { holes[hole2Idx].AddHole(holes[holeIdx]); holes.RemoveAt(holeIdx); --numHoles; bIncrementHoleIdx = false; break; } else { bool bIntersect = PolygonUtil.PolygonsIntersect2D(holes[holeIdx], holes[holeIdx].Bounds, holes[hole2Idx], holes[hole2Idx].Bounds); if (bIntersect) { // this is actually an error condition // fix by merging hole1 and hole2 into hole1 (including the holes inside hole2!) and delete hole2 // Then, because hole1 is now changed, restart it's check. PolygonOperationContext ctx = new PolygonOperationContext(); if (!ctx.Init(PolygonUtil.PolyOperation.Union | PolygonUtil.PolyOperation.Intersect, holes[holeIdx], holes[hole2Idx])) { if (ctx.mError == PolygonUtil.PolyUnionError.Poly1InsidePoly2) { holes[hole2Idx].AddHole(holes[holeIdx]); holes.RemoveAt(holeIdx); --numHoles; bIncrementHoleIdx = false; break; } else { throw new Exception("PolygonOperationContext.Init had an error during initialization"); } } PolygonUtil.PolyUnionError pue = PolygonUtil.PolygonOperation(ctx); if (pue == PolygonUtil.PolyUnionError.None) { Point2DList union = ctx.Union; Point2DList intersection = ctx.Intersect; // create a new contour for the union Contour c = new Contour(parent); c.AddRange(union); c.Name = "(" + holes[holeIdx].Name + " UNION " + holes[hole2Idx].Name + ")"; c.WindingOrder = Point2DList.WindingOrderType.Default; // add children from both of the merged contours int numChildHoles = holes[holeIdx].GetNumHoles(); for (int i = 0; i < numChildHoles; ++i) { c.AddHole(holes[holeIdx].GetHole(i)); } numChildHoles = holes[hole2Idx].GetNumHoles(); for (int i = 0; i < numChildHoles; ++i) { c.AddHole(holes[hole2Idx].GetHole(i)); } // make sure we preserve the contours of the intersection Contour cInt = new Contour(c); cInt.AddRange(intersection); cInt.Name = "(" + holes[holeIdx].Name + " INTERSECT " + holes[hole2Idx].Name + ")"; cInt.WindingOrder = Point2DList.WindingOrderType.Default; c.AddHole(cInt); // replace the current contour with the merged contour holes[holeIdx] = c; // toss the second contour holes.RemoveAt(hole2Idx); --numHoles; // current hole is "examined", so move to the next one hole2Idx = holeIdx + 1; } else { throw new Exception("PolygonOperation had an error!"); } } else { ++hole2Idx; } } } if (bIncrementHoleIdx) { ++holeIdx; } } numHoles = holes.Count; holeIdx = 0; while (holeIdx < numHoles) { int numPoints = holes[holeIdx].Count; for (int i = 0; i < numPoints; ++i) { int j = holes[holeIdx].NextIndex(i); uint constraintCode = TriangulationConstraint.CalculateContraintCode(holes[holeIdx][i], holes[holeIdx][j]); TriangulationConstraint tc = null; if (!cps.TryGetConstraint(constraintCode, out tc)) { tc = new TriangulationConstraint(holes[holeIdx][i], holes[holeIdx][j]); cps.AddConstraint(tc); } // replace the points in the holes with valid points if (holes[holeIdx][i].VertexCode == tc.P.VertexCode) { holes[holeIdx][i] = tc.P; } else if (holes[holeIdx][j].VertexCode == tc.P.VertexCode) { holes[holeIdx][j] = tc.P; } if (holes[holeIdx][i].VertexCode == tc.Q.VertexCode) { holes[holeIdx][i] = tc.Q; } else if (holes[holeIdx][j].VertexCode == tc.Q.VertexCode) { holes[holeIdx][j] = tc.Q; } } ++holeIdx; } }
public bool IsPointInside(TriangulationPoint p) { return(PolygonUtil.PointInPolygon2D(this, p)); }
// Assumes that points being passed in the list are connected and form a polygon. // Note that some error checking is done for robustness, but for the most part, // we have to rely on the user to feed us "correct" data public bool AddHole(List <TriangulationPoint> points) { if (points == null) { return(false); } //// split our self-intersection sections into their own lists List <Contour> pts = new List <Contour>(); int listIdx = 0; { Contour c = new Contour(this, points, WindingOrderType.Unknown); pts.Add(c); // only constrain the points if we actually HAVE a bounding rect if (MPoints.Count > 1) { // constrain the points to bounding rect int numPoints = pts[listIdx].Count; for (int i = 0; i < numPoints; ++i) { ConstrainPointToBounds(pts[listIdx][i]); } } } while (listIdx < pts.Count) { // simple sanity checking - remove duplicate coincident points before // we check the polygon: fast, simple algorithm that eliminate lots of problems // that only more expensive checks will find pts[listIdx].RemoveDuplicateNeighborPoints(); pts[listIdx].WindingOrder = WindingOrderType.Default; bool bListOk = true; PolygonError err = pts[listIdx].CheckPolygon(); while (bListOk && err != PolygonError.None) { if ((err & PolygonError.NotEnoughVertices) == PolygonError.NotEnoughVertices) { bListOk = false; continue; } if ((err & PolygonError.NotSimple) == PolygonError.NotSimple) { // split the polygons, remove the current list and add the resulting list to the end //List<Point2DList> l = TriangulationUtil.SplitSelfIntersectingPolygon(pts[listIdx], pts[listIdx].Epsilon); IEnumerable <Point2DList> l = PolygonUtil.SplitComplexPolygon(pts[listIdx], pts[listIdx].Epsilon); pts.RemoveAt(listIdx); foreach (Point2DList newList in l) { Contour c = new Contour(this); c.AddRange(newList); pts.Add(c); } err = pts[listIdx].CheckPolygon(); continue; } if ((err & PolygonError.Degenerate) == PolygonError.Degenerate) { pts[listIdx].Simplify(Epsilon); err = pts[listIdx].CheckPolygon(); continue; //err &= ~(PolygonError.Degenerate); //if (pts[listIdx].Count < 3) //{ // err |= PolygonError.NotEnoughVertices; // bListOK = false; // continue; //} } if ((err & PolygonError.AreaTooSmall) == PolygonError.AreaTooSmall || (err & PolygonError.SidesTooCloseToParallel) == PolygonError.SidesTooCloseToParallel || (err & PolygonError.TooThin) == PolygonError.TooThin || (err & PolygonError.Unknown) == PolygonError.Unknown) { bListOk = false; } // non-convex polygons are ok //if ((err & PolygonError.NotConvex) == PolygonError.NotConvex) //{ //} } if (!bListOk && pts[listIdx].Count != 2) { pts.RemoveAt(listIdx); } else { ++listIdx; } } bool bOk = true; listIdx = 0; while (listIdx < pts.Count) { int numPoints = pts[listIdx].Count; if (numPoints < 2) { // should not be possible by this point... ++listIdx; bOk = false; continue; } else if (numPoints == 2) { uint constraintCode = TriangulationConstraint.CalculateContraintCode(pts[listIdx][0], pts[listIdx][1]); TriangulationConstraint tc; if (!_constraintMap.TryGetValue(constraintCode, out tc)) { tc = new TriangulationConstraint(pts[listIdx][0], pts[listIdx][1]); AddConstraint(tc); } } else { Contour ph = new Contour(this, pts[listIdx], WindingOrderType.Unknown) { WindingOrder = WindingOrderType.Default, }; _holes.Add(ph); } ++listIdx; } return(bOk); }
public bool AddHole(List <TriangulationPoint> points, string name) { if (points == null) { return(false); } List <Contour> pts = new List <Contour>(); int listIdx = 0; { Contour c = new Contour(this, points, WindingOrderType.Unknown); pts.Add(c); if (mPoints.Count > 1) { int numPoints = pts[listIdx].Count; for (int i = 0; i < numPoints; ++i) { ConstrainPointToBounds(pts[listIdx][i]); } } } while (listIdx < pts.Count) { pts[listIdx].RemoveDuplicateNeighborPoints(); pts[listIdx].WindingOrder = Point2DList.WindingOrderType.Default; bool bListOK = true; Point2DList.PolygonError err = pts[listIdx].CheckPolygon(); while (bListOK && err != PolygonError.None) { if ((err & PolygonError.NotEnoughVertices) == PolygonError.NotEnoughVertices) { bListOK = false; continue; } if ((err & PolygonError.NotSimple) == PolygonError.NotSimple) { List <Point2DList> l = PolygonUtil.SplitComplexPolygon(pts[listIdx], pts[listIdx].Epsilon); pts.RemoveAt(listIdx); foreach (Point2DList newList in l) { Contour c = new Contour(this); c.AddRange(newList); pts.Add(c); } err = pts[listIdx].CheckPolygon(); continue; } if ((err & PolygonError.Degenerate) == PolygonError.Degenerate) { pts[listIdx].Simplify(this.Epsilon); err = pts[listIdx].CheckPolygon(); continue; } if ((err & PolygonError.AreaTooSmall) == PolygonError.AreaTooSmall || (err & PolygonError.SidesTooCloseToParallel) == PolygonError.SidesTooCloseToParallel || (err & PolygonError.TooThin) == PolygonError.TooThin || (err & PolygonError.Unknown) == PolygonError.Unknown) { bListOK = false; continue; } } if (!bListOK && pts[listIdx].Count != 2) { pts.RemoveAt(listIdx); } else { ++listIdx; } } bool bOK = true; listIdx = 0; while (listIdx < pts.Count) { int numPoints = pts[listIdx].Count; if (numPoints < 2) { ++listIdx; bOK = false; continue; } else if (numPoints == 2) { uint constraintCode = TriangulationConstraint.CalculateContraintCode(pts[listIdx][0], pts[listIdx][1]); TriangulationConstraint tc = null; if (!mConstraintMap.TryGetValue(constraintCode, out tc)) { tc = new TriangulationConstraint(pts[listIdx][0], pts[listIdx][1]); AddConstraint(tc); } } else { Contour ph = new Contour(this, pts[listIdx], Point2DList.WindingOrderType.Unknown); ph.WindingOrder = Point2DList.WindingOrderType.Default; ph.Name = name + ":" + listIdx.ToString(); mHoles.Add(ph); } ++listIdx; } return(bOK); }