public static double GetArea(PolygonList polygonList) { double totalArea = 0; polygonList.ForEach(polygon => totalArea += GetArea(polygon)); return(totalArea); }
public PolygonList Flatten() { PolygonList result = new PolygonList(); Clone()._flattenRecursive(ref result); return(result); }
public static PolygonList Execute(PolygonList a, PolygonList b, ClipType clipType) { PolyTree solution = new PolyTree(); Clipper clipper = new Clipper(); PolygonList a_flat = new PolygonList(); _addRecursive(a, ref a_flat); PolygonList b_flat = new PolygonList(); _addRecursive(b, ref b_flat); clipper.AddPaths(a_flat, PolyType.ptSubject, true); clipper.AddPaths(b_flat, PolyType.ptClip, true); clipper.Execute(clipType, solution); PolygonList solutionPolygons = new PolygonList(); foreach (PolyNode node in solution.Childs) { Polygon polygon = new Polygon(node); solutionPolygons.AddRange(polygon.Flatten()); } return(solutionPolygons); }
private static void _addRecursive(PolygonList hierarchicalList, ref PolygonList flatList) { foreach (Polygon polygon in hierarchicalList) { flatList.Add(polygon); _addRecursive(polygon.Holes, ref flatList); } }
public PolygonList GetPolygons(IncentiveType type) { PolygonList polygons = new PolygonList(); foreach (TimedArea area in GetAllAreas(type)) { polygons.Add(area.Area); } return(polygons); }
public static bool ContainsWithinEpsilon(PolygonList larger, Polygon smaller, double epsilon = (.01 * Vector.Scale * .01 * Vector.Scale)) { PolygonList intersections = Intersection(larger, smaller); if (intersections.Count != 1) { return(false); // @lukas should it be possible to have multiple? } return(EqualWithinEpsilon(smaller, intersections[0], epsilon)); }
/* comparer */ // todo this highly depends on what we mean. are the polygons overlapping? public bool Equals(PolygonList other) { if (other == null && !(Count == other.Count)) { return(false); } bool equals = true; PolygonList otherClone = other.Clone(); foreach (Polygon polygon in this) { Polygon equalPolygon; bool equalsAny = polygon.EqualsAny(otherClone, out equalPolygon); if (equalsAny) { otherClone.Remove(equalPolygon); } else { equals = false; break; } } if (otherClone.Count != 0) { return(false); } PolygonList thisClone = Clone(); foreach (Polygon polygon in other) { Polygon equalPolygon; bool equalsAny = polygon.EqualsAny(thisClone, out equalPolygon); if (equalsAny) { thisClone.Remove(equalPolygon); } else { equals = false; break; } } if (otherClone.Count != 0) { return(false); } return(equals); }
public static double ContainsRelative(PolygonList larger, Polygon smaller) { PolygonList intersections = Intersection(larger, smaller); double sharedArea = 0; foreach (Polygon intersection in intersections) { sharedArea += GetArea(intersection); } return(sharedArea / GetArea(smaller)); }
public static PolygonList OffsetPolygon(PolygonList poly, float absoluteDistance, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon) { ClipperOffset offset = new ClipperOffset(); offset.AddPaths(poly, joinType, endType); List <List <IntPoint> > solution = new List <List <IntPoint> >(); offset.Execute(ref solution, absoluteDistance * Vector.Scale); return(solution); }
// todo clearly define what equal means: cm difference in height+width maximal public static bool EqualWithinEpsilon(Polygon a, Polygon b, double epsilon = (.01 * Vector.Scale * .01 * Vector.Scale)) { PolygonList intersections = Intersection(a, b); if (intersections.Count != 1) { return(false); } double intersectionArea = Clipper.Area(intersections[0]); return((Math.Abs(intersectionArea - Clipper.Area(a)) < epsilon) && (Math.Abs(intersectionArea - Clipper.Area(b)) < epsilon)); }
public bool EqualsAny(PolygonList list, out Polygon equalPolygon) { foreach (Polygon polygon in list) { if (Equals(polygon)) { equalPolygon = polygon; return(true); } } equalPolygon = null; return(false); }
private void _flattenRecursive(ref PolygonList result) { foreach (Polygon polygon in Holes) { polygon._flattenRecursive(ref result); // if this is a contour, remove the hole's holes if (!IsHole) { polygon.Holes = new PolygonList(); } } // if this is a contour, add it to the result list if (!IsHole) { result.Add(this); } }
public void OverrideWith(TransitionFrame other) { Position.OverrideWith(other.Position); if (Area == null) { Area = other.Area; } else { Area.OverrideWith(other.Area); } if (TailArea == null) { TailArea = other.TailArea; } else { TailArea = other.TailArea; } }
public static PolygonList OffsetPolygonForSafety(PolygonList poly, float absoluteDistance, JoinType joinType = JoinType.jtMiter, EndType endType = EndType.etClosedPolygon, bool pretty = false) { //PolygonList contrast = Difference(TotalAssumedArea, poly); PolygonList contrast = Difference(TotalAssumedArea, poly); Func <Vector, bool> boundaryNotEdge = point => Math.Abs(point.X) > 1.999999 && Math.Abs(point.Z) < 1.999999 || Math.Abs(point.X) < 1.999999 && Math.Abs(point.Z) > 1.999999; Func <Vector, bool> notEdge = point => !(Math.Abs(point.X) < 2.000001 && Math.Abs(point.X) > 1.999999 && Math.Abs(point.Z) < 2.000001 && Math.Abs(point.Z) > 1.999999); if (pretty) { foreach (Polygon area in contrast) { // check if point is on bounds var numPoints = area.Points.Count; int numOnBoundaryNotEdge = 0; int numOnBoundaryNotEdgeNeighbor = 0; for (int i = 0; i < numPoints; i++) { var point = area.Points[i]; var isOnBoundaryNotEdge = boundaryNotEdge(point); if (isOnBoundaryNotEdge) { // check neighbors numOnBoundaryNotEdge++; var leftIndex = (i - 1 + numPoints) % numPoints; var rightIndex = (i + 1) % numPoints; var leftPoint = area.Points[leftIndex]; var rightPoint = area.Points[rightIndex]; // check if points are on bounds Vector extendTowards = Vector.Zero; if (notEdge(leftPoint)) { extendTowards = point - leftPoint; numOnBoundaryNotEdgeNeighbor++; } else if (notEdge(rightPoint)) { extendTowards = point - rightPoint; numOnBoundaryNotEdgeNeighbor++; } else { //throw new Exception("This probably shouldn't happen"); } area.Points[i] += 3 * extendTowards; } } //if (numOnBoundaryNotEdge != numOnBoundaryNotEdgeNeighbor) //{ // throw new ArgumentException(); //} } } contrast = OffsetPolygon(contrast, -absoluteDistance); PolygonList solution = Difference(poly, contrast); return(solution); //List<List<IntPoint>> finalSolution; //{ // Clipper c = new Clipper(); // c.AddPath(TotalAssumedArea, PolyType.ptSubject, true); // c.AddPaths(poly, PolyType.ptClip, true); // finalSolution = new List<List<IntPoint>>(); // c.Execute(ClipType.ctDifference, finalSolution); //} //{ // Clipper c = new Clipper(); // c.AddPaths(finalSolution, PolyType.ptSubject, true); // finalSolution = new List<List<IntPoint>>(); // c.Execute(ClipType.ctUnion, finalSolution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); //} //contrast = OffsetPolygon(contrast, -absoluteDistance); //PolygonList solution = Difference(poly, contrast); //solution = OffsetPolygon(solution, -.01f); //solution = Union(solution, solution); //PolygonList unified = new PolygonList(); //foreach (Polygon polygon in solution) //{ // unified = Union(polygon, unified); //} //solution = Union(TotalAssumedArea, solution); //Clipper clipper = new Clipper(); //clipper.AddPaths(solution, PolyType.ptSubject, true); ////PolyTree finalSolution = new PolyTree(); //List<List<IntPoint>> finalSolution = new List<List<IntPoint>>(); //clipper.Execute(ClipType.ctUnion, finalSolution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); //return finalSolution; }
public static bool HaveIntersection(PolygonList a, Polygon b) { var solution = Intersection(a, b); return(solution.Count > 0); }
public static PolygonList Intersection(PolygonList a, PolygonList b) { return(Execute(a, b, ClipType.ctIntersection)); }
/// <summary> /// Creates a polygon from another polygon's able shape and checks is it is an hole. /// Note: If you want to keep the holes, use Clone(). /// </summary> /// <param name="polygon">The polygon whose shape should be copied</param> /// <param name="holes">The polygon's holes</param> public Polygon(Polygon polygon, PolygonList holes = null) : this(new List <Vector>(polygon.Points), holes) { }
/// <summary> /// Creates a polygon from a list of Vectors and checks is it is an hole. /// </summary> /// <param name="vectorList">The list of vectors for initializing the polygon</param> /// <param name="holes">The polygon's holes</param> public Polygon(List <Vector> vectorList, PolygonList holes = null) { Points = vectorList; IsHole = !_isCCW(vectorList); Holes = holes ?? new PolygonList(); }
public static PolygonList Intersection(PolygonList a, Polygon b) { return(Intersection(a, new PolygonList { b })); }
/// <summary> /// Creates an empty polygon. /// </summary> public Polygon() { Points = new List <Vector>(); IsHole = false; Holes = new PolygonList(); }
public static PolygonList Union(PolygonList a, PolygonList b) { return(Execute(a, b, ClipType.ctUnion)); }
public bool EqualsAny(PolygonList list) { Polygon equalPolygon; return(EqualsAny(list, out equalPolygon)); }
public static PolygonList Difference(PolygonList a, PolygonList b) { return(Execute(a, b, ClipType.ctDifference)); }
public static PolygonList Intersection(Polygon a, PolygonList b) { return(Intersection(b, a)); }