public static List <List <Vector2> > Simplify(List <Vector2> polygon, FillMode fillMode, out PolyTree tree) { Clipper.Clear(); Clipper.AddPath(polygon, PolyType.ptSubject, true); Clipper.AddPath(polygon, PolyType.ptClip, true); tree = new PolyTree(); PolyFillType fillType = fillMode.ToPolyFillType(); Clipper.Execute(ClipType.ctUnion, tree, fillType, fillType); return(Clipper.ClosedPathsFromPolyTree(tree)); }
/// <summary> /// Returns a region which is the result of mergin region1 and region2. Original regions are not modified. /// </summary> /// <returns>The merge.</returns> /// <param name="region1">Region1.</param> /// <param name="region2">Region2.</param> public Region RegionMerge(Region region1, Region region2) { Region newRegion = region1.Clone(); RegionMagnet(newRegion, region2); Clipper clipper = new Clipper(); clipper.AddPath(newRegion, PolyType.ptSubject); clipper.AddPath(region2, PolyType.ptClip); clipper.Execute(ClipType.ctUnion, newRegion); return(newRegion); }
private List <List <Vector2> > GetIntersectionPolygon(Vector2[] subjectPoly, out bool isIntersecting) { List <List <Vector2> > intersectionPoly = new List <List <Vector2> >(); Clipper clipper = new Clipper(); Paths solutionPath = new Paths(); Path subjPath = new Path(); Path clipPath = new Path(); int len, len2; isIntersecting = true; len = subjectPoly.Length; for (int i = 0; i < len; i++) { subjPath.Add(new IntPoint(subjectPoly[i].x * scaleFactor, subjectPoly[i].y * scaleFactor)); } len = clipPolygon.Count; for (int i = 0; i < len; i++) { clipPath.Add(new IntPoint(clipPolygon[i].x * scaleFactor, clipPolygon[i].y * scaleFactor)); } clipper.AddPath(subjPath, PolyType.ptSubject, true); clipper.AddPath(clipPath, PolyType.ptClip, true); clipper.Execute(ClipType.ctIntersection, solutionPath, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); if (solutionPath.Count != 0) { len = solutionPath.Count; for (int i = 0; i < len; i++) { len2 = solutionPath[i].Count; List <Vector2> list = new List <Vector2>(); for (int j = 0; j < len2; j++) { list.Add(new Vector2(solutionPath[i][j].X / scaleFactor, solutionPath[i][j].Y / scaleFactor)); } intersectionPoly.Add(list); } return(intersectionPoly); } else { isIntersecting = false; return(null); } }
private IntersectResult Intersect2Curves(Curve a, Curve b) { int clipperPrecision = 100; IntersectResult result = new IntersectResult(); if (Curve.PlanarCurveCollision(a, b, Plane.WorldXY, 0.001f)) { Clipper clipper = new Clipper(); Path subjectA = CurveToPath(a, clipperPrecision); Path subjectB = CurveToPath(b, clipperPrecision); Paths solution = new Paths(); clipper.AddPath(subjectA, PolyType.ptClip, true); clipper.AddPath(subjectB, PolyType.ptSubject, true); clipper.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); if (solution.Count > 0) { result.intersect = true; PolylineCurve pl = PathToPolyline(solution[0], clipperPrecision); result.unionCurve = pl; Point3d minPoint = pl.GetBoundingBox(false).Min; Point3d maxPoint = pl.GetBoundingBox(false).Max; if (maxPoint.X - minPoint.X > maxPoint.Y - minPoint.Y) { result.reboundingVector = new Vector2d(0, -(maxPoint.Y - minPoint.Y)); if (AreaMassProperties.Compute(a).Centroid.Y > AreaMassProperties.Compute(b).Centroid.Y) { result.reboundingVector.Y *= -1; } } else { result.reboundingVector = new Vector2d(-(maxPoint.X - minPoint.X), 0); if (AreaMassProperties.Compute(a).Centroid.X > AreaMassProperties.Compute(b).Centroid.X) { result.reboundingVector.X *= -1; } } } } else { result.intersect = false; result.reboundingVector = Vector2d.Unset; result.unionCurve = null; } return(result); }
public static PolyNode mergeSubjPathAndClipPath(Path subj_p, Path clip_p) { Clipper c = new Clipper(Clipper.ioPreserveCollinear); c.AddPath(subj_p, PolyType.ptSubject, true); c.AddPath(clip_p, PolyType.ptClip, true); PolyTree polyTree = new AXClipperLib.PolyTree(); c.Execute(ClipType.ctDifference, polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); return(polyTree); }
/// <summary> /// Checks whether this key overlaps with another specified key definition. /// </summary> /// <param name="otherKey">The other key to check for overlapping on.</param> /// <returns><c>True</c> if the keys overlap, <c>false</c> otherwise.</returns> public bool BordersWith(MouseKeyDefinition otherKey) { var clipper = new Clipper(); clipper.AddPath(this.GetPath(), PolyType.ptSubject, true); clipper.AddPath(otherKey.GetPath(), PolyType.ptClip, true); var union = new List <List <IntPoint> >(); clipper.Execute(ClipType.ctUnion, union); return(union.Count == 1); }
/// <summary> /// Tests if the supplied Polygon shares one or more areas with this Polygon when compared on a shared plane. /// </summary> /// <param name="polygon">The Polygon to compare with this Polygon.</param> /// <returns> /// Returns true if the supplied Polygon shares one or more areas with this Polygon when compared on a shared plane. Returns false if the supplied Polygon does not share an area with this Polygon or if the supplied Polygon is null. /// </returns> public bool Intersects(Polygon polygon) { if (polygon == null) { return(false); } var clipper = new Clipper(); var solution = new List <List <IntPoint> >(); clipper.AddPath(this.ToClipperPath(), PolyType.ptSubject, true); clipper.AddPath(polygon.ToClipperPath(), PolyType.ptClip, true); clipper.Execute(ClipType.ctIntersection, solution); return(solution.Count != 0); }
public void MergeAdjacentRegions(IAdminEntity entity) { // Searches for adjacency - merges in first region int regionCount = entity.regions.Count; for (int k = 0; k < regionCount; k++) { Region region1 = entity.regions [k]; if (region1 == null || region1.points == null || region1.points.Length == 0) { continue; } for (int j = k + 1; j < regionCount; j++) { Region region2 = entity.regions [j]; if (region2 == null || region2.points == null || region2.points.Length == 0) { continue; } if (!region1.Intersects(region2)) { continue; } RegionMagnet(region1, region2); Clipper clipper = new Clipper(); clipper.AddPath(region1, PolyType.ptSubject); clipper.AddPath(region2, PolyType.ptClip); clipper.Execute(ClipType.ctUnion); // Add new neighbours int rnCount = region2.neighbours.Count; for (int n = 0; n < rnCount; n++) { Region neighbour = region2.neighbours [n]; if (neighbour != null && neighbour != region1 && !region1.neighbours.Contains(neighbour)) { region1.neighbours.Add(neighbour); } } // Remove merged region entity.regions.RemoveAt(j); region1.sanitized = false; j = k; regionCount--; entity.mainRegionIndex = 0; // will need to refresh country definition later in the process } } }
private IEnumerable <IPath> Clip(IPath shape, params IPath[] hole) { Clipper clipper = new Clipper(); clipper.AddPath(shape, ClippingType.Subject); if (hole != null) { foreach (IPath s in hole) { clipper.AddPath(s, ClippingType.Clip); } } return(clipper.GenerateClippedShapes()); }
/// <summary> /// Clips the rulings to the area. /// <para>Warning: force xMin to be in p1, xMax to be in p2, might lead to odd stuff if not vertical or horizontal.</para> /// </summary> /// <param name="rulings"></param> /// <param name="area"></param> public static List <Ruling> CropRulingsToArea(IReadOnlyList <Ruling> rulings, PdfRectangle area) { // use clipper var clipper = new Clipper(); clipper.AddPath(Clipper.ToClipperIntPoints(area), PolyType.ptClip, true); foreach (Ruling r in rulings) { clipper.AddPath(Clipper.ToClipperIntPoints(r), PolyType.ptSubject, false); } var solutions = new PolyTree(); if (clipper.Execute(ClipType.ctIntersection, solutions)) { List <Ruling> rv = new List <Ruling>(); foreach (var solution in solutions.Childs) { var x0 = solution.Contour[0].X / 10_000.0; var x1 = solution.Contour[1].X / 10_000.0; double xmin = Math.Min(x0, x1); double xmax = Math.Max(x0, x1); // warning // force xmin to be in p1, xmax to be in p2, might lead to odd stuff if not vertic or horiz // do not bother with y for the moment, will throw an error anyway in Ruling() // needed for testExtractColumnsCorrectly3() and testSpreadsheetExtractionIssue656() to succeed rv.Add(new Ruling(new PdfPoint(xmin, solution.Contour[0].Y / 10_000.0), new PdfPoint(xmax, solution.Contour[1].Y / 10_000.0))); } return(rv); } else { return(new List <Ruling>()); } //List<Ruling> rv = new List<Ruling>(); //foreach (Ruling r in rulings) //{ // if (r.intersects(area)) // { // rv.Add(r.intersect(area)); // } //} //return rv; }
void CountrySubstractCountryEnclaves(int countryIndex, Region region, Poly2Tri.Polygon poly) { List <Region> negativeRegions = new List <Region> (); int countryCount = _countriesOrderedBySize.Count; for (int ops = 0; ops < countryCount; ops++) { int op = _countriesOrderedBySize [ops]; if (op == countryIndex) { continue; } Country opCountry = _countries [op]; Region opCountryRegion = opCountry.regions [opCountry.mainRegionIndex]; if (opCountryRegion.points.Length >= 5 && opCountry.mainRegion.rect2DArea < region.rect2DArea && opCountryRegion.rect2D.Overlaps(region.rect2D, true)) { if (region.Contains(opCountryRegion)) // just check main region of province for speed purposes { negativeRegions.Add(opCountryRegion.Clone()); } } } // Collapse negative regions in big holes for (int nr = 0; nr < negativeRegions.Count - 1; nr++) { for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++) { if (negativeRegions [nr].Intersects(negativeRegions [nr2])) { Clipper clipper = new Clipper(); int control = negativeRegions [nr].points.Length; clipper.AddPath(negativeRegions [nr], PolyType.ptSubject); clipper.AddPath(negativeRegions [nr2], PolyType.ptClip); clipper.Execute(ClipType.ctUnion); negativeRegions.RemoveAt(nr2); nr = -1; break; } } } // Substract holes for (int r = 0; r < negativeRegions.Count; r++) { Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(negativeRegions [r].points); poly.AddHole(polyHole); } }
public void addShapeCollider(List <Vector2> points, Vector3 position) { points = new List <Vector2>(points); updatePointList(points, position); List <List <IntPoint> > pathclip = filterCollider(Vector2ArrayToListIntPoint(points.ToArray())); if (pathclip.Count == 0) { return; } if (collider.pathCount == 0) { for (int i = 0; i < pathclip.Count; i++) { collider.pathCount = i + 1; collider.SetPath(i, ListIntPointToVector2Array(pathclip[i])); } return; } else { Clipper c = new Clipper(); foreach (List <IntPoint> p in pathclip) { c.AddPath(p, PolyType.ptClip, true); } for (int i = 0; i < collider.pathCount; i++) { c.AddPath(Vector2ArrayToListIntPoint(collider.GetPath(i)), PolyType.ptSubject, true); } List <List <IntPoint> > solution = new List <List <IntPoint> >(); c.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); collider.pathCount = solution.Count; for (int i = 0; i < solution.Count; i++) { collider.SetPath(i, ListIntPointToVector2Array(solution[i])); } } }
/// <summary> /// Sets the Collider in Children as Difference or Intersection from baseCollider with Clippers /// </summary> /// <param name="ct">ct.Intersection or ct.Difference based on Operation you want to do</param> /// <param name="clippers">list of Polygons to intersect/difference the baseCollider</param> void SetColliderAs(ClipType ct, List <PolygonCollider2D> clippers) { List <List <IntPoint> > solution = new List <List <IntPoint> >(); Clipper clipper = new Clipper(); List <IntPoint> subj = new List <IntPoint>(); for (int j = 0; j < baseCollider.Count; j++) { subj.Add(ConvertToIntPoint(transform.localToWorldMatrix * baseCollider[j] + (Vector4)transform.position)); } foreach (PolygonCollider2D cl in clippers) { List <IntPoint> clip = new List <IntPoint>(); for (int j = 0; j < cl.points.Length; j++) { clip.Add(ConvertToIntPoint(cl.transform.localToWorldMatrix * cl.points[j] + (Vector4)cl.transform.position)); } clipper.AddPath(clip, PolyType.ptClip, true); } clipper.AddPath(subj, PolyType.ptSubject, true); if (ct == ClipType.ctDifference) { clipper.Execute(ct, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } if (ct == ClipType.ctIntersection) { clipper.Execute(ct, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } childPolyCollider.pathCount = solution.Count; for (int i = 0; i < solution.Count; i++) { List <Vector2> unitedPolygon = new List <Vector2>(); foreach (IntPoint point in solution[i]) { unitedPolygon.Add(transform.worldToLocalMatrix * (ConvertToVector2(point) - (Vector2)transform.position)); } childPolyCollider.SetPath(i, unitedPolygon.ToArray()); } }
/// <summary> /// Constructs the geometric differences between this Line and the supplied Polygons. /// </summary> /// <param name="diffs">The list of intersecting Polygons.</param> /// <returns> /// Returns a list of Lines representing the subtraction of the Lines intersecting the supplied list of Polygons. /// </returns> public static List <Line> Differences(this Line line, IList <Polygon> diffs) { var thisPath = LineToClipper(line); var polyPaths = new List <List <IntPoint> >(); foreach (Polygon poly in diffs) { polyPaths.Add(Shaper.PolygonToClipper(poly)); } Clipper clipper = new Clipper(); clipper.AddPath(thisPath, PolyType.ptSubject, false); clipper.AddPaths(polyPaths, PolyType.ptClip, true); var solution = new PolyTree(); clipper.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd); var soLines = Clipper.OpenPathsFromPolyTree(solution); var lines = new List <Line>(); foreach (List <IntPoint> path in soLines) { lines.Add(LineFromClipper(path.ToList())); } return(lines); }
/// <summary> /// Updates the key definition to occupy a region of itself plus the specified other keys. /// </summary> /// <param name="keys">The keys to union with.</param> /// <returns>A new key definition with the updated region.</returns> private KeyboardKeyDefinition UnionWith(IList <KeyboardKeyDefinition> keys) { var newBoundaries = this.Boundaries.Select(b => new TPoint(b.X, b.Y)).ToList(); if (keys.Any()) { var cl = new Clipper(); cl.AddPath(this.GetPath(), PolyType.ptSubject, true); cl.AddPaths(keys.Select(x => x.GetPath()).ToList(), PolyType.ptClip, true); var union = new List <List <IntPoint> >(); cl.Execute(ClipType.ctUnion, union); if (union.Count > 1) { throw new ArgumentException("Cannot union two non-overlapping keys."); } newBoundaries = union.Single().ConvertAll <TPoint>(x => x); } return(new KeyboardKeyDefinition( this.Id, newBoundaries, this.KeyCodes, this.Text, this.ShiftText, this.ChangeOnCaps)); }
/// <summary> /// 处理主通道占据空间 直接 转义为 clipper 语境 /// </summary> public Paths HandleMainRoadSpace(CurveArray mianRoadCurves, CurveArray roadCurves, double MainRoadWidth, double roadWidth) { int mainRoadCurvesCount = mianRoadCurves.Size; Paths mainRoadRegion = new Paths();//地库主车道占据空间 if (mainRoadCurvesCount == 0) { return(mainRoadRegion); } else if (mainRoadCurvesCount > 0) { Paths wdMainOffset = new Paths();//拿到所有的主车道偏移后的围合点,需要将围合区域做并集 foreach (Curve _curve in mianRoadCurves) { wdMainOffset.Add(clipper_methods._GetOffsetPonts_clipper_line(_curve, MainRoadWidth / 2));//添加每根车道中心线偏移后的矩形点集 } foreach (Curve _curve in roadCurves) { wdMainOffset.Add(clipper_methods._GetOffsetPonts_clipper_line(_curve, roadWidth / 2)); //添加每根车道中心线偏移后的矩形点集 } Clipper cTemp = new Clipper(); //开展 所有线段的偏移矩形点击进行 clipper 合并 cTemp.AddPaths(wdMainOffset, PolyType.ptSubject, true); cTemp.AddPath(wdMainOffset.First(), PolyType.ptClip, true); cTemp.Execute(ClipType.ctUnion, mainRoadRegion, PolyFillType.pftNonZero, PolyFillType.pftNonZero);//需要把每根主车道偏移出的空间,进行合并 } return(mainRoadRegion); }
public void Execute(ref List <List <IntPoint> > solution, double delta) { solution.Clear(); FixOrientations(); DoOffset(delta); Clipper clipper = new Clipper(0); clipper.AddPaths(m_destPolys, PolyType.ptSubject, true); if (delta > 0.0) { clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } else { IntRect bounds = ClipperBase.GetBounds(m_destPolys); List <IntPoint> list = new List <IntPoint>(4); list.Add(new IntPoint(bounds.left - 10, bounds.bottom + 10)); list.Add(new IntPoint(bounds.right + 10, bounds.bottom + 10)); list.Add(new IntPoint(bounds.right + 10, bounds.top - 10)); list.Add(new IntPoint(bounds.left - 10, bounds.top - 10)); clipper.AddPath(list, PolyType.ptSubject, true); clipper.ReverseSolution = true; clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); if (solution.Count > 0) { solution.RemoveAt(0); } } }
/// <summary> /// Returns true if the rectangle and the line intersect. /// Takes in account the rectangle border by expanding its area by 1 on each side. /// <para>Uses clipper.</para> /// </summary> /// <param name="line">The line to check.</param> public bool IntersectsLine(PdfLine line) { var clipper = new Clipper(); clipper.AddPath(Clipper.ToClipperIntPoints(Expand(this.BoundingBox)), PolyType.ptClip, true); clipper.AddPath(Clipper.ToClipperIntPoints(line), PolyType.ptSubject, false); var solutions = new PolyTree(); if (clipper.Execute(ClipType.ctIntersection, solutions)) { return(solutions.Childs.Count > 0); } return(false); }
private void UpdatePlayerOverlap() { if (CurrentOnsetDrawing == _collidedBeatIndex || CurrentOnset >= Onsets.Count) { ParentStage.Overlap = 0; return; } var c = new Clipper(); c.AddPaths(_onsetDrawing.GetPolygonBounds(CurrentOnsetDrawing), PolyType.ptSubject, true); if (CurrentOnsetDrawing < _onsetDrawing.DrawingCount - 1) { c.AddPaths(_onsetDrawing.GetPolygonBounds(CurrentOnsetDrawing + 1), PolyType.ptSubject, true); } c.AddPath(Player.GetBounds(), PolyType.ptClip, true); var soln = new List <List <IntPoint> >(); c.Execute(ClipType.ctIntersection, soln); //ParentStage.Overlap = soln.Count > 0 ? (int)((Clipper.Area(soln[0]) / Clipper.Area(Player.GetBounds())) * 100) : 0; ParentStage.Overlap = 0; foreach (var a in soln) { ParentStage.Overlap += (int)((Clipper.Area(a) / Clipper.Area(Player.GetBounds())) * (100.0f)); } if (ParentStage.Overlap > 80) { ParentStage.Multiplier = -1; Player.Hits++; _collidedBeatIndex = CurrentOnsetDrawing; //_polygons[_collidedBeatIndex].SetColour(_colours.EvenCollisionColour, _colours.EvenCollisionOutlineColour, _colours.OddCollisionColour, _colours.OddCollisionOutlienColour); CenterPolygon.SetColour(_colours.EvenCollisionColour, _colours.EvenCollisionOutlineColour, _colours.OddCollisionColour, _colours.OddCollisionOutlienColour); } }
public void GenerateMarchingSquaresAndLines(Action <double, string> progressReporter, ImageBuffer image, IThresholdFunction thresholdFunction) { if (image != null) { // Regenerate outline var marchingSquaresData = new MarchingSquaresByte( image, thresholdFunction.ZeroColor, thresholdFunction.Threshold, 0); progressReporter?.Invoke(0, "Creating Outline"); marchingSquaresData.CreateLineSegments(); progressReporter?.Invoke(.1, null); int pixelsToIntPointsScale = 1000; var lineLoops = marchingSquaresData.CreateLineLoops(pixelsToIntPointsScale); progressReporter?.Invoke(.15, null); var min = new IntPoint(-10, -10); var max = new IntPoint(10 + image.Width * pixelsToIntPointsScale, 10 + image.Height * pixelsToIntPointsScale); var boundingPoly = new Polygon(); boundingPoly.Add(min); boundingPoly.Add(new IntPoint(min.X, max.Y)); boundingPoly.Add(max); boundingPoly.Add(new IntPoint(max.X, min.Y)); // now clip the polygons to get the inside and outside polys var clipper = new Clipper(); clipper.AddPaths(lineLoops, PolyType.ptSubject, true); clipper.AddPath(boundingPoly, PolyType.ptClip, true); var polygonShape = new Polygons(); progressReporter?.Invoke(.3, null); clipper.Execute(ClipType.ctIntersection, polygonShape); progressReporter?.Invoke(.55, null); polygonShape = Clipper.CleanPolygons(polygonShape, 100); progressReporter?.Invoke(.75, null); VertexStorage rawVectorShape = polygonShape.PolygonToPathStorage(); var aabb = this.VisibleMeshes().FirstOrDefault().GetAxisAlignedBoundingBox(); var xScale = aabb.XSize / image.Width; var affine = Affine.NewScaling(1.0 / pixelsToIntPointsScale * xScale); affine *= Affine.NewTranslation(-aabb.XSize / 2, -aabb.YSize / 2); rawVectorShape.transform(affine); this.VertexSource = rawVectorShape; progressReporter?.Invoke(1, null); } }
public static Polygons GetCorrectedWinding(this Polygons polygonsToFix) { polygonsToFix = Clipper.CleanPolygons(polygonsToFix); Polygon boundsPolygon = new Polygon(); IntRect bounds = Clipper.GetBounds(polygonsToFix); bounds.left -= 10; bounds.bottom += 10; bounds.right += 10; bounds.top -= 10; boundsPolygon.Add(new IntPoint(bounds.left, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.bottom)); boundsPolygon.Add(new IntPoint(bounds.left, bounds.bottom)); Clipper clipper = new Clipper(); clipper.AddPaths(polygonsToFix, PolyType.ptSubject, true); clipper.AddPath(boundsPolygon, PolyType.ptClip, true); PolyTree intersectionResult = new PolyTree(); clipper.Execute(ClipType.ctIntersection, intersectionResult); Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult); return(outputPolygons); }
//public Paths intersection(Paths other_pologon) //{ // Paths solution3 = new Paths(); // Clipper co1 = new Clipper(0); //不知道怎么用,在Polygons中有使用 // co1.AddPaths(polygons, ClipperLib.PolyType.ptSubject, true); // co1.AddPaths(other_pologon,ClipperLib.PolyType.ptClip,true); // co1.Execute(ClipperLib.ClipType.ctIntersection, solution3); // return solution3; //} public Paths intersection(Paths other_pologon, int rownum, ref List <maddtionpologonIndex> outAddtionPathsIndex) { Paths solution4 = new Paths(); Path tempnull = new Path(); //用来占位用 2016-04-22 for (int j = 0; j < polygons.Count; j++) { Paths solution3 = new Paths(); Clipper co1 = new Clipper(0); //不知道怎么用,在Polygons中有使用 //之前使用04_22晚间 co1.AddPath(polygons[j], ClipperLib.PolyType.ptSubject, true); co1.AddPaths(other_pologon, ClipperLib.PolyType.ptClip, true); //co1.AddPath(temppath, ClipperLib.PolyType.ptClip, true); //co1.AddPaths(other_pologon, ClipperLib.PolyType.ptSubject, true); co1.Execute(ClipperLib.ClipType.ctIntersection, solution3); //为了占位,形成n*n的格子,不相交的地方用空格子占位,由于一次只比较一个格子,所以只有一个分区块,不考虑被分成两部分 if (solution3.Count < 1) { solution4.Add(tempnull); } else { solution4.Add(solution3[0]); for (int i = 1; i < solution3.Count; ++i) { outAddtionPathsIndex.Add(new maddtionpologonIndex(solution3[i], rownum, j)); } } } return(solution4); }
private void Clip(NavigationPolygon floor, NavigationPolygons staticObjects) { Clipper clipper = new Clipper(); if (!clipper.AddPath(floor, PolyType.ptSubject, true)) { throw new Exception("Can't add Paths (Subject)."); } if (staticObjects.Count > 0 && !clipper.AddPaths(staticObjects, PolyType.ptClip, true)) { throw new Exception("Can't add Paths (Clip)."); } // we do it twice (it's easier than deep copy the polygons), since this is loading screen time... We don't mind performance too much here if (!clipper.Execute(ClipType.ctDifference, floorWithStaticObjects, PolyFillType.pftNonZero)) { throw new Exception("Can't clip floorWithStaticObjects."); } if (!clipper.Execute(ClipType.ctDifference, FloorWithDynamicObjects, PolyFillType.pftNonZero)) { throw new Exception("Can't clip floorWithStaticObjects."); } clipper.Reset(); }
private Polygons FixWinding(Polygons polygonsToPathAround) { polygonsToPathAround = Clipper.CleanPolygons(polygonsToPathAround); Polygon boundsPolygon = new Polygon(); IntRect bounds = Clipper.GetBounds(polygonsToPathAround); bounds.minX -= 10; bounds.maxY += 10; bounds.maxX += 10; bounds.minY -= 10; boundsPolygon.Add(new IntPoint(bounds.minX, bounds.minY)); boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.minY)); boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.maxY)); boundsPolygon.Add(new IntPoint(bounds.minX, bounds.maxY)); Clipper clipper = new Clipper(); clipper.AddPaths(polygonsToPathAround, PolyType.ptSubject, true); clipper.AddPath(boundsPolygon, PolyType.ptClip, true); PolyTree intersectionResult = new PolyTree(); clipper.Execute(ClipType.ctIntersection, intersectionResult); Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult); return(outputPolygons); }
private Polygons FixWinding(Polygons polygonsToPathAround) { polygonsToPathAround = Clipper.CleanPolygons(polygonsToPathAround); Polygon boundsPolygon = new Polygon(); IntRect bounds = Clipper.GetBounds(polygonsToPathAround); bounds.left -= 10; bounds.bottom += 10; bounds.right += 10; bounds.top -= 10; boundsPolygon.Add(new IntPoint(bounds.left, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.bottom)); boundsPolygon.Add(new IntPoint(bounds.left, bounds.bottom)); Clipper clipper = new Clipper(); clipper.AddPaths(polygonsToPathAround, PolyType.ptSubject, true); clipper.AddPath(boundsPolygon, PolyType.ptClip, true); PolyTree intersectionResult = new PolyTree(); clipper.Execute(ClipType.ctIntersection, intersectionResult); Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult); Clipper.ReversePaths(outputPolygons); return(outputPolygons); }
//------------------------------------------------------------------------------ public void Execute(ref List <List <IntPoint> > solution, double delta) { solution.Clear(); FixOrientations(); DoOffset(delta); //now clean up 'corners' ... Clipper clpr = new Clipper(); clpr.AddPaths(m_destPolys, PolyType.ptSubject, true); if (delta > 0) { clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } else { IntRect r = Clipper.GetBounds(m_destPolys); List <IntPoint> outer = new List <IntPoint>(4); outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.top - 10)); outer.Add(new IntPoint(r.left - 10, r.top - 10)); clpr.AddPath(outer, PolyType.ptSubject, true); clpr.ReverseSolution = true; clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); if (solution.Count > 0) { solution.RemoveAt(0); } } }
/// <summary> /// Constructs the geometric difference between this Polygon and the supplied Polygons. /// </summary> /// <param name="difPolys">The list of intersecting Polygons.</param> /// <param name="tolerance">An optional tolerance value.</param> /// <returns> /// Returns a list of Polygons representing the subtraction of the supplied Polygons from this Polygon. /// Returns null if the area of this Polygon is entirely subtracted. /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect. /// </returns> public IList <Polygon> Difference(IList <Polygon> difPolys, double tolerance = Vector3.EPSILON) { var thisPath = this.ToClipperPath(tolerance); var polyPaths = new List <List <IntPoint> >(); foreach (Polygon polygon in difPolys) { polyPaths.Add(polygon.ToClipperPath(tolerance)); } Clipper clipper = new Clipper(); clipper.AddPath(thisPath, PolyType.ptSubject, true); clipper.AddPaths(polyPaths, PolyType.ptClip, true); var solution = new List <List <IntPoint> >(); clipper.Execute(ClipType.ctDifference, solution); if (solution.Count == 0) { return(null); } var polygons = new List <Polygon>(); foreach (List <IntPoint> path in solution) { try { polygons.Add(PolygonExtensions.ToPolygon(path.Distinct().ToList(), tolerance)); } catch { // swallow invalid polygons } } return(polygons); }
public static Polygons GetCorrectedWinding(this Polygons polygonsToFix) { polygonsToFix = Clipper.CleanPolygons(polygonsToFix); var boundsPolygon = new Polygon(); IntRect bounds = Clipper.GetBounds(polygonsToFix); bounds.minX -= 10; bounds.minY -= 10; bounds.maxY += 10; bounds.maxX += 10; boundsPolygon.Add(new IntPoint(bounds.minX, bounds.minY)); boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.minY)); boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.maxY)); boundsPolygon.Add(new IntPoint(bounds.minX, bounds.maxY)); var clipper = new Clipper(); clipper.AddPaths(polygonsToFix, PolyType.ptSubject, true); clipper.AddPath(boundsPolygon, PolyType.ptClip, true); var intersectionResult = new PolyTree(); clipper.Execute(ClipType.ctIntersection, intersectionResult); Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult); return(outputPolygons); }
/// <summary> /// Constructs the geometric difference between this Polygon and the supplied Polygons. /// </summary> /// <param name="difPolys">The list of intersecting Polygons.</param> /// <returns> /// Returns a list of Polygons representing the subtraction of the supplied Polygons from this Polygon. /// Returns null if the area of this Polygon is entirely subtracted. /// Returns a list containing a representation of the perimeter of this Polygon if the two Polygons do not intersect. /// </returns> public IList <Polygon> Difference(IList <Polygon> difPolys) { var thisPath = this.ToClipperPath(); var polyPaths = new List <List <IntPoint> >(); foreach (Polygon polygon in difPolys) { polyPaths.Add(polygon.ToClipperPath()); } Clipper clipper = new Clipper(); clipper.AddPath(thisPath, PolyType.ptSubject, true); clipper.AddPaths(polyPaths, PolyType.ptClip, true); var solution = new List <List <IntPoint> >(); clipper.Execute(ClipType.ctDifference, solution); if (solution.Count == 0) { return(null); } var polygons = new List <Polygon>(); foreach (List <IntPoint> path in solution) { polygons.Add(PolygonExtensions.ToPolygon(path.Distinct().ToList())); } return(polygons); }
IEnumerator AddHexagons(IAdminEntity[] entities) { Cell[] cells = _map.cells; Clipper clipper = new Clipper(); for (int j = 0; j < cells.Length; j++) { if (j % 100 == 0) { if (hexifyContext.progress != null) { if (hexifyContext.progress((float)j / cells.Length, hexifyContext.title, "Pass 3/6: adding hexagons to frontiers...")) { cancelled = true; hexifyContext.finish(true); yield break; } } yield return(null); } int entityIndex = procCells [j].entityIndex; if (entityIndex < 0) { continue; } Cell cell = cells [j]; // Create a region for the cell IAdminEntity entity = entities [entityIndex]; Vector2[] newPoints = new Vector2[6]; for (int k = 0; k < 6; k++) { newPoints [k].x = hexagonPoints [k].x + cell.center.x; newPoints [k].y = hexagonPoints [k].y + cell.center.y; } procCells [j].cellRegion = new Region(entity, entity.regions.Count); procCells [j].cellRegion.UpdatePointsAndRect(newPoints); // Add region to target entity's polygon - only if the entity is touching or crossing target entity frontier Region targetRegion = procCells [j].entityRegion; clipper.Clear(); clipper.AddPath(targetRegion, PolyType.ptSubject); clipper.AddPath(procCells [j].cellRegion, PolyType.ptClip); clipper.Execute(ClipType.ctUnion); } }
//------------------------------------------------------------------------------ public List<List<Point>> Execute(double deltap, double eps = double.Epsilon) { var solution = new List<List<Point>>(); FixPerimeters(); DoOffset(deltap, eps); //now clean up 'corners' ... var clpr = new Clipper(); clpr.AddPaths(destPolys, PolyType.Subject); if (deltap > 0) { clpr.Execute(ClipType.Union, solution, PolyFillType.Positive, PolyFillType.Positive); } else { var r = destPolys.GetBounds(); var outer = new List<Point>(4) { new Point(r.Left - 10, r.Bottom + 10), new Point(r.Right + 10, r.Bottom + 10), new Point(r.Right + 10, r.Top - 10), new Point(r.Left - 10, r.Top - 10) }; clpr.AddPath(outer, PolyType.Subject); clpr.ReverseSolution = true; clpr.Execute(ClipType.Union, solution, PolyFillType.Negative, PolyFillType.Negative); if (solution.Count > 0) solution.RemoveAt(0); } return solution; }
public static Polygons GetCorrectedWinding(this Polygons polygonsToFix) { polygonsToFix = Clipper.CleanPolygons(polygonsToFix); Polygon boundsPolygon = new Polygon(); IntRect bounds = Clipper.GetBounds(polygonsToFix); bounds.left -= 10; bounds.bottom += 10; bounds.right += 10; bounds.top -= 10; boundsPolygon.Add(new IntPoint(bounds.left, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.top)); boundsPolygon.Add(new IntPoint(bounds.right, bounds.bottom)); boundsPolygon.Add(new IntPoint(bounds.left, bounds.bottom)); Clipper clipper = new Clipper(); clipper.AddPaths(polygonsToFix, PolyType.ptSubject, true); clipper.AddPath(boundsPolygon, PolyType.ptClip, true); PolyTree intersectionResult = new PolyTree(); clipper.Execute(ClipType.ctIntersection, intersectionResult); Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult); return outputPolygons; }
private static void AddPath(Clipper clipper, Path path) { foreach (Subpath subpath in path.Subpaths) { if (!subpath.IsSinglePointClosed() && !subpath.IsSinglePointOpen()) { IList<Point2D> linearApproxPoints = subpath.GetPiecewiseLinearApproximation(); clipper.AddPath(ConvertToIntPoints(linearApproxPoints), PolyType.ptSubject, subpath.Closed); } } }
private static void AddRect(Clipper clipper, Point2D[] rectVertices, PolyType polyType) { clipper.AddPath(ConvertToIntPoints(new List<Point2D>(rectVertices)), polyType, true); }