public static Paths WPPolygon(Obj_AI_Hero Hero, float delay) { List <Vector2Time> HeroPath = Hero.GetWaypointsWithTime(); Vector2 myPath; Paths WPPaths = new Paths(); for (var i = 0; i < HeroPath.Count() - 1; i++) { if (HeroPath.ElementAt <Vector2Time>(i + 1).Time <= delay) { Geometry.Polygon.Rectangle WPRectangle = new Geometry.Polygon.Rectangle(HeroPath.ElementAt <Vector2Time>(i).Position, HeroPath.ElementAt <Vector2Time>(i + 1).Position, Hero.BoundingRadius); Geometry.Polygon.Circle Box = new Geometry.Polygon.Circle(HeroPath.ElementAt <Vector2Time>(i).Position, Hero.BoundingRadius); WPPaths.Add(Box.ToClipperPath()); WPPaths.Add(WPRectangle.ToClipperPath()); } else { myPath = PositionAfter(Hero, delay, Hero.MoveSpeed); Geometry.Polygon.Rectangle WPRectangle = new Geometry.Polygon.Rectangle(HeroPath.ElementAt <Vector2Time>(i).Position, myPath, Hero.BoundingRadius); Geometry.Polygon.Circle Box = new Geometry.Polygon.Circle(myPath, Hero.BoundingRadius); WPPaths.Add(Box.ToClipperPath()); WPPaths.Add(WPRectangle.ToClipperPath()); break; } } Geometry.Polygon.Circle WPFirstBox = new Geometry.Polygon.Circle(HeroPath.First <Vector2Time>().Position, Hero.BoundingRadius); WPPaths.Add(WPFirstBox.ToClipperPath()); return(WPPaths); }
public static VertexStorage PolygonToPathStorage(this Polygons polygons) { var output = new VertexStorage(); foreach (Polygon polygon in polygons) { bool first = true; foreach (IntPoint point in polygon) { if (first) { output.Add(point.X, point.Y, ShapePath.FlagsAndCommand.MoveTo); first = false; } else { output.Add(point.X, point.Y, ShapePath.FlagsAndCommand.LineTo); } } output.ClosePolygon(); } output.Add(0, 0, ShapePath.FlagsAndCommand.Stop); return(output); }
public static double SingleUnoccupiedBoundaryArea(Shape boundaryShape, Shape shape) { if (boundaryShape == null) { return(0.0); } Paths boundarySolution = new Paths(1); Paths boundaryPaths = new Paths(1); Paths shapesWithinBoundaries = new Paths(1); shapesWithinBoundaries.Add(new Path(shape.GetDrawingCoordinates())); boundaryPaths.Add(new Path(boundaryShape.GetDrawingCoordinates())); Clipper c = new Clipper(); c.AddPolygons(boundaryPaths, PolyType.ptSubject); c.AddPolygons(shapesWithinBoundaries, PolyType.ptClip); c.Execute(ClipType.ctDifference, boundarySolution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); var totalShapeArea = Utils.PolygonSignedArea(shapesWithinBoundaries); var boundaryIntersection = Utils.PolygonSignedArea(boundarySolution); Logger.SimpleDebug("Area of shapes within boundary is " + boundaryIntersection + " out of " + totalShapeArea); return((totalShapeArea - boundaryIntersection) * Config.IntersectionErrorModifier); }
private static void InterceptionQ(Obj_AI_Hero Enemy) { Geometry.Polygon.Circle Qspellpoly = new Geometry.Polygon.Circle(PreCastPos(Enemy, 0.6f), 130f); Paths subjs = new Paths(); foreach (var bla in WPPolygon(Enemy).ToPolygons()) { subjs.Add(bla.ToClipperPath()); } Paths clips = new Paths(1); clips.Add(Qspellpoly.ToClipperPath()); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subjs, PolyType.ptSubject, true); c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution); foreach (var bli in solution.ToPolygons()) { bli.Draw(System.Drawing.Color.Blue); } }
public static double UnoccupiedBoundaryArea(Shape boundaryShape, List <Shape> shapes, Form1 form) { Paths boundarySolution = new Paths(1); Paths boundaryPaths = new Paths(1); Paths shapesWithinBoundaries = new Paths(1); foreach (var shape in shapes) { shapesWithinBoundaries.Add(new Path(shape.GetDrawingCoordinates())); } boundaryPaths.Add(new Path(boundaryShape.GetDrawingCoordinates())); Utils.DrawPolygons(boundaryPaths, Color.Green, false, form); Clipper c = new Clipper(); c.AddPolygons(boundaryPaths, PolyType.ptSubject); c.AddPolygons(shapesWithinBoundaries, PolyType.ptClip); c.Execute(ClipType.ctIntersection, boundarySolution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); Utils.DrawPolygons(boundarySolution, Color.Orange, true, form); var totalShapeArea = Utils.PolygonSignedArea(shapesWithinBoundaries); var boundaryIntersection = Utils.PolygonSignedArea(boundarySolution); Logger.SimpleDebug("Area of shapes within boundary is " + boundaryIntersection + " out of " + totalShapeArea); return((totalShapeArea - boundaryIntersection) * Config.IntersectionErrorModifier); }
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 void Interceptiontest(Obj_AI_Hero Enemy, float delay, float Range, float varRange) { Geometry.Polygon.Circle Qspellpoly = new Geometry.Polygon.Circle(LastQCastpos, Q.Width); Qspellpoly.Draw(System.Drawing.Color.Khaki); Paths subjs = new Paths(); foreach (var Waypoint in WPPolygon(Enemy, delay).ToPolygons()) { subjs.Add(Waypoint.ToClipperPath()); } Paths clips = new Paths(1); clips.Add(Qspellpoly.ToClipperPath()); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subjs, PolyType.ptSubject, true); c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution); foreach (var bli in solution.ToPolygons()) { bli.Draw(System.Drawing.Color.Blue); } }
private static Polygon ClprPathsToPolygon(Paths polygons) { Polygon result = null; if (polygons.Count <= 0) { return(null); } result = new Polygon(polygons.Count); for (int j = 0; j < polygons.Count; ++j) { bool hole = !Clipper.Orientation(polygons[j]); List <Vec2d> contour = new List <Vec2d>(polygons[j].Count); for (int i = 0; i < polygons[j].Count; ++i) { IntPoint p = polygons[j][i]; double x = p.X / PrecisionScale; double y = p.Y / PrecisionScale; contour.Add(new Vec2d(x, y)); } result.SetContourAndHole(j, contour, hole); } return(result); }
public static List<List<Vector2>> clip(List<Vector2> boundary, List<Vector2> region) { Polygons boundaryPoly = createPolygons(boundary); Polygons regionPoly = createPolygons(region); //clip triangular polygon against the boundary polygon Polygons result = new Polygons(); Clipper c = new Clipper(); c.AddPaths(regionPoly, PolyType.ptClip, true); c.AddPaths(boundaryPoly, PolyType.ptSubject, true); c.Execute(ClipType.ctIntersection, result, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); List<List<Vector2>> clippedPolygons = new List<List<Vector2>>(); foreach (Polygon poly in result) { List<Vector2> clippedPoly = new List<Vector2>(); foreach (IntPoint p in poly) { clippedPoly.Add(new Vector2(p.X, p.Y) / multiplier); } clippedPolygons.Add(clippedPoly); } return clippedPolygons; }
public static Vector2[] Extend(this Vector2[] points, float radius) { if (Mathf.Approximately(radius, 0)) { return(points); } Path polygon = points.ToList().ConvertAll(p => new IntPoint(p.x, p.y)); Paths solution = new Paths(); ClipperOffset c = new ClipperOffset(); c.AddPath(polygon, JoinType.jtRound, EndType.etClosedPolygon); c.Execute(ref solution, radius); var r = solution.Count > 0 ? solution[0].ConvertAll(p => new Vector2(p.X, p.Y)) : new List <Vector2>(); if (r.Count > 0) { r.Add(r[0]); } return(r.ToArray()); }
public static void Interceptiontest(AIHeroClient Enemy, float delay, float Range) { Geometry.Polygon.Circle Qspellpoly = new Geometry.Polygon.Circle(PreCastPos(Enemy, Range, delay), 130f); Qspellpoly.Draw(System.Drawing.Color.Khaki); Paths subjs = new Paths(); foreach (var bla in WPPolygon(Enemy, delay).ToPolygons()) { subjs.Add(bla.ToClipperPath()); } Paths clips = new Paths(1); clips.Add(Qspellpoly.ToClipperPath()); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subjs, PolyType.ptSubject, true); c.AddPaths(clips, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution); foreach (var bli in solution.ToPolygons()) { bli.Draw(System.Drawing.Color.Blue); } }
static void Main(string[] args) { Paths subj = new Paths(2); subj.Add(new Path(4)); subj[0].Add(new IntPoint(180, 200)); subj[0].Add(new IntPoint(260, 200)); subj[0].Add(new IntPoint(260, 150)); subj[0].Add(new IntPoint(180, 150)); subj.Add(new Path(3)); subj[1].Add(new IntPoint(215, 160)); subj[1].Add(new IntPoint(230, 190)); subj[1].Add(new IntPoint(200, 190)); Paths clip = new Paths(1); clip.Add(new Path(4)); clip[0].Add(new IntPoint(190, 210)); clip[0].Add(new IntPoint(240, 210)); clip[0].Add(new IntPoint(240, 130)); clip[0].Add(new IntPoint(190, 130)); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); }
internal void AddClipperPolygonsToCarve(ClipPaths r, double cuttingdepth, double rapiddepth, double maxstepdown) { MoveTo(x, y, rapiddepth, GCodeFile.MoveMode.Fast); List<double> cuts = new List<double>(); double depthstepcount = (0 - cuttingdepth) / maxstepdown; double depthstep = (0 - cuttingdepth) / Math.Ceiling(depthstepcount); for (double depth = 0 - depthstep; depth>cuttingdepth;depth-=depthstep) { cuts.Add(depth); } if (cuts.Last() != cuttingdepth) cuts.Add(cuttingdepth); foreach (var d in cuts) { foreach (var a in r) { MoveTo(a[0].X / 100000.0, a[0].Y / 100000.0, rapiddepth, GCodeFile.MoveMode.Fast); MoveTo(a[0].X / 100000.0, a[0].Y / 100000.0, d, GCodeFile.MoveMode.ReallySlow); bool first = true; foreach (var v in a) { if (!first) { MoveTo(v.X / 100000.0, v.Y / 100000.0, d, MoveMode.Slow); } else { first = false; } } MoveTo(a[0].X / 100000.0, a[0].Y / 100000.0, d); MoveTo(a[0].X / 100000.0, a[0].Y / 100000.0, rapiddepth, GCodeFile.MoveMode.ReallySlow); } } }
/// <summary> /// Creates Paths from Polygon list for Clipper /// </summary> /// <param name="plist">Polygon</param> /// <returns>Clipper Paths of Polygons</returns> public static Paths MakePaths(params Geometry.Polygon[] plist) { var ps = new Paths(plist.Length); ps.AddRange(plist.Select(t => t.ToClipperPath())); return(ps); }
public void GenerateBase(Polygons polygonShape, double bottomWithoutBase) { if (polygonShape != null && polygonShape.Select(p => p.Count).Sum() > 3) { Polygons polysToOffset = new Polygons(); switch (BaseType) { case BaseTypes.Rectangle: polysToOffset.Add(GetBoundingPolygon(polygonShape)); break; case BaseTypes.Circle: polysToOffset.Add(GetBoundingCircle(polygonShape)); break; case BaseTypes.Outline: PolyTree polyTreeForBase = GetPolyTree(polygonShape); foreach (PolyNode polyToOffset in polyTreeForBase.Childs) { polysToOffset.Add(polyToOffset.Contour); } break; } if (polysToOffset.Count > 0) { Polygons basePolygons; if (BaseType == BaseTypes.Outline && InfillAmount > 0) { basePolygons = polysToOffset.Offset((BaseSize + InfillAmount) * scalingForClipper); basePolygons = basePolygons.Offset(-InfillAmount * scalingForClipper); } else { basePolygons = polysToOffset.Offset(BaseSize * scalingForClipper); } basePolygons = ClipperLib.Clipper.CleanPolygons(basePolygons, 10); VertexStorage rawVectorShape = basePolygons.PolygonToPathStorage(); var vectorShape = new VertexSourceApplyTransform(rawVectorShape, Affine.NewScaling(1.0 / scalingForClipper)); var baseObject = new Object3D() { Mesh = VertexSourceToMesh.Extrude(vectorShape, zHeight: ExtrusionHeight) }; Children.Add(baseObject); baseObject.Mesh.Translate(new Vector3(0, 0, -ExtrusionHeight + bottomWithoutBase)); } else { // clear the mesh Mesh = null; } } }
public void AddPolygons(Polygons Polies) { foreach (var a in Polies) { AddPolygon(a); } }
public static double SingleShapeIntersection(Shape shape, Shape externalShape) { if (externalShape == null) { return(0.0); } Paths subject = new Paths(1); Paths collidingClips = new Paths(1); // Add shape to subject subject = new Paths(1); subject.Add(new Path(shape.GetDrawingCoordinates())); // Find all shapes with collision distance and add to temporary clib collidingClips = new Paths(2); collidingClips.Add(new Path(externalShape.GetDrawingCoordinates())); Paths solution = new Paths(1); Clipper c = new Clipper(); c.AddPolygons(subject, PolyType.ptSubject); c.AddPolygons(collidingClips, PolyType.ptClip); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); var intersectionError = Utils.PolygonSignedArea(solution); Logger.SimpleDebug("Area of intersection for shape " + shape.Index + " is " + intersectionError); return(intersectionError * Config.IntersectionErrorModifier); }
//Apply a polygon clipper operation on subject vertices using cut vertices public static List<Vector2[]> ClipPoly(Vector2[] subject, Vector2[] cut, ClipType operation) { List<Vector2[]> cutPolygons = new List<Vector2[]>(); Paths subj = new Paths(1); subj.Add(Vector2ToIntList(subject)); Paths clip = new Paths(1); clip.Add(Vector2ToIntList(cut)); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(operation,solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); /* for(int i = 0; i<solution.Count; i++){ if( Mathf.Abs((float)Clipper.Area(solution[i])) > ignoreArea){ cutPolygons.Add( IntListToVector2( solution[i] )); } } */ return IntListsToVector2(solution); }
// polygons treatment private Polygons getPolygonsInRegion(int i, int j, double delta) { //converting the boundingbox of the region to a polygon Polygon clip = this.BoundingBoxToPolygon(this.ReagionsBoundingBoxes[i, j]); //initial polygons denote part of the subregions that are located within the region Polygons initialPolygons = new Polygons(); Clipper c = new Clipper(); //c.StrictlySimple = true; // jeremy c.AddPolygons(this.IntRoads, PolyType.ptSubject); c.AddPolygon(clip, PolyType.ptClip); c.Execute(ClipType.ctIntersection, initialPolygons, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); // negative Clip is the roads inside the region clipping the region Polygons negativeClip = new Polygons(); Clipper negative = new Clipper(); //negative.StrictlySimple = true; // jeremy negative.AddPolygons(initialPolygons, PolyType.ptClip); negative.AddPolygon(clip, PolyType.ptSubject); negative.Execute(ClipType.ctIntersection, negativeClip, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); //shrinking the negative clip to remove common edges Polygons negativeShrank = Clipper.OffsetPolygons(negativeClip, -1 * Math.Pow(10, this.Exponent - 1), ClipperLib.JoinType.jtMiter); // expanding the negative shrink the negative clip to remove common edges Polygons negativeShrankExpand = Clipper.OffsetPolygons(negativeShrank, Math.Pow(10, this.Exponent - 1) + 3, ClipperLib.JoinType.jtMiter); Polygons negativeShrankExpandNegative = new Polygons(); Clipper negativeAgain = new Clipper(); //negativeAgain.StrictlySimple = true; // jeremy negativeAgain.AddPolygons(negativeShrankExpand, PolyType.ptSubject); negativeAgain.AddPolygon(clip, PolyType.ptClip); negativeAgain.Execute(ClipType.ctIntersection, negativeShrankExpandNegative, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); return(negativeShrankExpandNegative); }
IMoveableSection GetCutPolygon(List <Point2D> CuttingRectanglePoints) { #region GPC ////Cutting polygon //Polygon CuttingPoly = new Polygon(); //CuttingPoly.AddContour(CuttingRectanglePoints, false); ////Original polygon //Polygon OriginalPoly = new Polygon(); //OriginalPoly.AddContour(Vertices, false); //Polygon result = OriginalPoly.Clip(GpcOperation.Intersection, CuttingPoly); //GenericShape shape = new GenericShape(result); //return shape; #endregion #region Clipper Paths subj = GetPolyPaths(Vertices); Paths clip = GetPolyPaths(CuttingRectanglePoints); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); GenericShape shape = new GenericShape(solution); return(shape); #endregion }
public static List <List <Vector2> > clip(List <Vector2> boundary, List <Vector2> region) { ClipperLibPolygons boundaryPoly = createPolygons(boundary); ClipperLibPolygons regionPoly = createPolygons(region); //clip triangular polygon against the boundary polygon ClipperLibPolygons result = new ClipperLibPolygons(); Clipper c = new Clipper(); c.AddPaths(regionPoly, PolyType.ptClip, true); c.AddPaths(boundaryPoly, PolyType.ptSubject, true); c.Execute(ClipType.ctIntersection, result, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); List <List <Vector2> > clippedPolygons = new List <List <Vector2> >(); foreach (ClipperLibPolygon poly in result) { List <Vector2> clippedPoly = new List <Vector2>(); foreach (IntPoint p in poly) { clippedPoly.Add(new Vector2(p.X, p.Y) / multiplier); } clippedPolygons.Add(clippedPoly); } return(clippedPolygons); }
private static Polygon GetBoundingPolygon(Polygons basePolygons) { var min = new IntPoint(long.MaxValue, long.MaxValue); var max = new IntPoint(long.MinValue, long.MinValue); foreach (Polygon polygon in basePolygons) { foreach (IntPoint point in polygon) { min.X = Math.Min(point.X - 10, min.X); min.Y = Math.Min(point.Y - 10, min.Y); max.X = Math.Max(point.X + 10, max.X); max.Y = Math.Max(point.Y + 10, max.Y); } } 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)); return(boundingPoly); }
public void GenerateCollision() { //List<List<Vector2>> polygons = new List<List<Vector2>>(); List <List <Vector2> > unitedPolygons = new List <List <Vector2> >(); Clipper clipper = new Clipper(); int scalingFactor = 10000; for (int x = 0; x < layer.chunkSize_x; x++) { for (int y = 0; y < layer.chunkSize_y; y++) { if (grid[x, y] != null && grid[x, y].colider) { Path newPoligons = new Path(4); newPoligons.Add(new IntPoint(Mathf.Floor((0 + x) * scalingFactor), Mathf.Floor((0 + y) * scalingFactor))); newPoligons.Add(new IntPoint(Mathf.Floor((0 + x) * scalingFactor), Mathf.Floor((1 + y) * scalingFactor))); newPoligons.Add(new IntPoint(Mathf.Floor((1 + x) * scalingFactor), Mathf.Floor((1 + y) * scalingFactor))); newPoligons.Add(new IntPoint(Mathf.Floor((1 + x) * scalingFactor), Mathf.Floor((0 + y) * scalingFactor))); clipper.AddPath(newPoligons, PolyType.ptSubject, true); } } } Paths solution = new Paths(); clipper.Execute(ClipType.ctUnion, solution); ClipperOffset offset = new ClipperOffset(); offset.AddPaths(solution, JoinType.jtMiter, EndType.etClosedPolygon); offset.Execute(ref solution, 5f); foreach (Path path in solution) { List <Vector2> unitedPolygon = new List <Vector2>(); foreach (IntPoint point in path) { unitedPolygon.Add(new Vector2(point.X / (float)scalingFactor, point.Y / (float)scalingFactor)); } unitedPolygons.Add(unitedPolygon); } unitedPolygons = TileMap.RemoveClosePointsInPolygons(unitedPolygons); PolygonCollider2D collider = layer.map.gameObject.GetComponent <PolygonCollider2D>(); collider.pathCount = unitedPolygons.Count; for (int i = 0; i < unitedPolygons.Count; i++) { Vector2[] points = unitedPolygons[i].ToArray(); collider.SetPath(i, points); } }
/** * Computes the area of a shape */ public static double Area(Paths paths) { // Sum up the area of all shapes. // // Note that we divide the area by the square of the precision. This is because when creating the shapes, all // floating point values are converted into integers by multiplying them with the precision. return(paths.Sum(Clipper.Area) / (precision * precision)); }
//this function takes a list of polygons as a parameter, this list of polygons represent all the polygons that constitute collision in your level. public List <List <Vector2> > UniteCollisionPolygons(List <List <Vector2> > polygons) { //this is going to be the result of the method List <List <Vector2> > unitedPolygons = new List <List <Vector2> >(); Clipper clipper = new Clipper(); //clipper only works with ints, so if we're working with floats, we need to multiply all our floats by //a scaling factor, and when we're done, divide by the same scaling factor again int scalingFactor = 10000; //this loop will convert our List<List<Vector2>> to what Clipper works with, which is "Path" and "IntPoint" //and then add all the Paths to the clipper object so we can process them for (int i = 0; i < polygons.Count; i++) { Path allPolygonsPath = new Path(polygons[i].Count); for (int j = 0; j < polygons[i].Count; j++) { allPolygonsPath.Add(new IntPoint(Mathf.Floor(polygons[i][j].x * scalingFactor), Mathf.Floor(polygons[i][j].y * scalingFactor))); //print(new IntPoint(Mathf.Floor(polygons[i][j].x * scalingFactor), Mathf.Floor(polygons[i][j].y * scalingFactor)).X + ", " + new IntPoint(Mathf.Floor(polygons[i][j].x * scalingFactor), Mathf.Floor(polygons[i][j].y * scalingFactor)).Y); } clipper.AddPath(allPolygonsPath, PolyType.ptSubject, true); } //this will be the result Paths solution = new Paths(); //having added all the Paths added to the clipper object, we tell clipper to execute an union clipper.Execute(ClipType.ctUnion, solution); //the union may not end perfectly, so we're gonna do an offset in our polygons, that is, expand them outside a little bit ClipperOffset offset = new ClipperOffset(); offset.AddPaths(solution, JoinType.jtMiter, EndType.etClosedPolygon); //5 is the amount of offset offset.Execute(ref solution, 0.1f); //now we just need to convert it into a List<List<Vector2>> while removing the scaling foreach (Path path in solution) { List <Vector2> unitedPolygon = new List <Vector2>(); foreach (IntPoint point in path) { unitedPolygon.Add(new Vector2(point.X / (float)scalingFactor, point.Y / (float)scalingFactor)); } unitedPolygons.Add(unitedPolygon); } //this removes some redundant vertices in the polygons when they are too close from each other //may be useful to clean things up a little if your initial collisions don't match perfectly from tile to tile unitedPolygons = RemoveClosePointsInPolygons(unitedPolygons); //everything done return(unitedPolygons); }
/// <summary> /// returns a clipper paths list of all enemy champion positions /// </summary> public Paths GetEnemyPaths() { var enemyPaths = new Paths(GetEnemyPosList().Count); for (int i = 0; i < GetEnemyPosList().Count; i++) { enemyPaths[i].Add(new IntPoint(GetEnemyPosList().ToArray()[i].X, GetEnemyPosList().ToArray()[i].Y)); } return enemyPaths; }
/// <summary> /// Returns a clipper path list of all ally champions /// </summary> public Paths GetAllyPaths() { var allyPaths = new Paths(GetAllyPosList().Count); for (int i = 0; i < GetAllyPosList().Count; i++) { allyPaths[i].Add(new IntPoint(GetAllyPosList().ToArray()[i].X + Randoms.Rand.Next(-150, 150), GetAllyPosList().ToArray()[i].Y + Randoms.Rand.Next(-150, 150))); } return allyPaths; }
private IEnumerable <CPolygon> GrowAndClipMergedCpg_Overlap(CPolygon mergedcpg, double dblProp, string strSimplification, string strBufferStyle, double dblMiterLimit) { //dblProp = 0.2; //dblProp = 1; double dblCurrentScale = _dblStartScale + dblProp * (_dblTargetScale - _dblStartScale); double dblCurrentGrow = dblProp * _dblTotalGrow * CConstants.dblFclipper; double dblCurrentEpsilon = Math.Min(dblCurrentGrow / dblMiterLimit, _dblEpsilon * dblCurrentScale * CConstants.dblFclipper); double dblCurrentErosion = _dblErosion * dblCurrentScale * CConstants.dblFclipper; //double dblCurrentDilation = Math.Max(dblCurrentEpsilon / 2, dblProp * _dblDilation * dblCurrentScale * CConstants.dblFclipper); double dblCurrentDilation = (dblCurrentGrow - dblMiterLimit * dblCurrentErosion) / (dblMiterLimit - 1); //dblCurrentErosion = 0; //dblCurrentDilation = 0; var clipPathsFirstLevel = clipperMethods.GenerateClipPathsByCpgEb(mergedcpg.ClipCpgLt); var LastAndClippedPath = new Paths(); if (mergedcpg.SubCpgLt == null || mergedcpg.SubCpgLt.Count < 2) { LastAndClippedPath.AddRange(DilateErodeOffsetSimplifyCpg(mergedcpg, dblCurrentGrow, dblCurrentDilation, dblCurrentErosion, dblCurrentEpsilon, strSimplification, strBufferStyle, dblMiterLimit)); } else { //var SubCpgLt = mergedcpg.SubCpgLt; var submergedcpglt = MergeCloseCpgsAndAddBridges(mergedcpg.SubCpgLt, false, //---Merge---// dblCurrentGrow, dblCurrentDilation, dblCurrentEpsilon); //var BridgeCpipeDt = mergedcpg.BridgeCpipeDt; foreach (var submergedcpg in submergedcpglt) { LastAndClippedPath.AddRange(DilateErodeOffsetSimplifyCpg(submergedcpg, dblCurrentGrow, dblCurrentDilation, dblCurrentErosion, dblCurrentEpsilon, strSimplification, strBufferStyle, dblMiterLimit)); } } //CSaveFeature.SaveCEdgeEb(clipperMethods.ScaleCEdgeEb( // clipperMethods.ConvertPathsToCEdgeEb(LastAndClippedPath, true), 1 / CConstants.dblFclipper), // "GrownPathsWithoutMergeOrClip", blnVisible: false); LastAndClippedPath.AddRange(mergedcpg.LastTimePaths); var unitedPaths = clipperMethods.Clip_Paths(LastAndClippedPath, true, mergedcpg.LastTimePaths, true, ClipType.ctUnion); //var unitedPaths = LastAndClippedPath; var clippedPolyTree = clipperMethods.Clip_PolyTree(unitedPaths, true, clipPathsFirstLevel, true, ClipType.ctIntersection); mergedcpg.LastTimePaths = Clipper.PolyTreeToPaths(clippedPolyTree); var GrownAndClippedCpg = clipperMethods.GenerateCpgEbByPolyTree(clippedPolyTree, mergedcpg.ID, true); //CSaveFeature.SavePolyTreeAsCpgEb(clippedPolyTree, "GrownMergeClipPolyTree", // pesriSimpleFillStyle: esriSimpleFillStyle.esriSFSNull, blnVisible: false); return(GrownAndClippedCpg); }
public TriggerColliderData(Collider2D newCollider, Paths newPath, Bounds newBounds) { collider = newCollider; center = collider.bounds.center; particleMagic = newCollider.GetComponent <ParticleMagic>(); element = particleMagic.GetElement(); path = newPath; bounds = newBounds; }
public void FixPolygonWindings() { Polygons solution2 = new Polygons(); /* * if (false) * { * for (int i = 0; i < DisplayShapes.Count; i++) * { * Polygons clips = new Polygons(); * * clips.Add(DisplayShapes[i].toPolygon()); * Clipper cp = new Clipper(); * cp.AddPolygons(solution2, PolyType.ptSubject); * cp.AddPolygons(clips, PolyType.ptClip); * * cp.Execute(ClipType.ctXor, solution2, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); * } * } * else */ { Polygons clips = new Polygons(); for (int i = 0; i < DisplayShapes.Count; i++) { clips.Add(DisplayShapes[i].toPolygon()); } Clipper cp = new Clipper(); cp.AddPolygons(solution2, PolyType.ptSubject); cp.AddPolygons(clips, PolyType.ptClip); cp.Execute(ClipType.ctXor, solution2, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); } OutlineShapes.Clear(); for (int i = 0; i < solution2.Count; i++) { int ID = i; if (State != null) { ID = State.LastShapeID++; } PolyLine PL = new PolyLine(ID); PL.fromPolygon(solution2[i]); // if (Clipper.Orientation(solution2[i]) == false) // { // // PL.Vertices.Reverse(); // } PL.MyColor = Color.FromArgb(255, 200, 128, 0); OutlineShapes.Add(PL); } }
/// <summary> /// Returns a clipper path list of all ally champions /// </summary> public static Paths GetAllyPaths() { var allyPaths = new Paths(GetAllyPosList().Count); for (int i = 0; i < GetAllyPosList().Count; i++) { var randomizedAllyPos = GetAllyPosList().ToArray()[i].Randomize(-150, 150); allyPaths[i].Add(new IntPoint(randomizedAllyPos.X, randomizedAllyPos.Y)); } return allyPaths; }
public static List<Vector2[]> IntListsToVector2(Paths paths) { List<Vector2[]> verticesList = new List<Vector2[]>(paths.Count); for(int i = 0; i<paths.Count; i++){ if( Mathf.Abs((float)Clipper.Area(paths[i])) > ignoreArea){ verticesList.Add( IntListToVector2( paths[i] )); } } return verticesList; }
private void ClosePoly() { if (CurrentPolygon.Vertices.Count == 0) { return; } CurrentPolygon.Closed = true; Polygons.Add(CurrentPolygon); CurrentPolygon = new Polygon("untransformedSVG"); }
/// <summary> /// Creates Paths from Polygon list for Clipper /// </summary> /// <param name="plist">Polygon</param> /// <returns>Clipper Paths of Polygons</returns> public static Paths MakePaths(params Geometry.Polygon[] plist) { Paths ps = new Paths(plist.Length); for (int i = 0; i < plist.Length; i++) { ps.Add(plist[i].ToClipperPath()); } return(ps); }
// Union Polylines private Polygons XOR(List <Polygon> polygons) { Polygons results = new Polygons(); Clipper c = new Clipper(); c.AddPolygons(polygons, PolyType.ptSubject); //c.StrictlySimple = true; c.Execute(ClipType.ctXor, results, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); return(Clipper.SimplifyPolygons(results)); }
//Clipper public static List <Polygon> ToPolygons(this Paths v) { var result = new List <Polygon>(); foreach (var path in v) { result.Add(path.ToPolygon()); } return(result); }
public void DoCircleClipping(Vector2 pos, float radius) { List<VertexPosition[]> shape_old = shape; bool isCleared = false; int sc = 0; for (sc = 0; sc < shape_old.Count; sc++) { ClippingPolygons subj = new ClippingPolygons(1); subj.Add(new ClippingPolygon(shape_old[sc].Length)); foreach (VertexPosition point in shape_old[sc]) { subj[0].Add(new IntPoint((int)((point.Position.X) * accuracy), (int)((point.Position.Y) * accuracy))); } ClippingPolygons clip = new ClippingPolygons(1); clip.Add(new ClippingPolygon()); for (int alpha = 0; alpha < 360; alpha += 10) { clip[0].Add(new IntPoint((int)(((Math.Sin((alpha) * Math.PI / 180.0) * radius) + pos.X) * accuracy), (int)(((Math.Cos((alpha) * Math.PI / 180.0) * radius) + pos.Y) * accuracy))); //log.Log(pos.ToString()); } ClippingPolygons solution = new ClippingPolygons(); Clipper c = new Clipper(); c.AddPolygons(subj, PolyType.ptSubject); c.AddPolygons(clip, PolyType.ptClip); if (c.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd)) { if (!isCleared) { shape = new List<VertexPosition[]>(); drawer.Clear(); isCleared = true; } for (int f = 0; f < solution.Count; f++) { shape.Add(new VertexPosition[solution[f].Count]); drawer.Add(new ChunkDrawer(ref log)); for (int i = 0; i < solution[f].Count; i++) { shape[shape.Count-1][i] = new VertexPosition(solution[f][i].X / accuracy, solution[f][i].Y / accuracy, 0); } drawer[shape.Count-1].BufferVertices(shape[shape.Count - 1]); } } } }
private static Polygons createPolygons(Triangle tri) { Polygons poly = new Polygons(1); poly.Add(new Polygon(3)); for (int i = 0; i < 3; i++) { poly[0].Add(new IntPoint(tri.sites[i].x * multiplier, tri.sites[i].y * multiplier)); } return poly; }
// perform xor public static Paths ClipperXor(this Polygon clip, Polygon subject) { var subj = new Paths(); subj.Add(subject.ToClipperPath()); var clp = new Paths(); clp.Add(clip.ToClipperPath()); var result = new Paths(); var c = new Clipper(); c.Execute(ClipType.ctXor, result, PolyFillType.pftPositive, PolyFillType.pftPositive); return result; }
private static Polygons createPolygons(List<Vector2> source) { Polygons poly = new Polygons(1); poly.Add(new Polygon(source.Count)); foreach (Vector2 p in source) { poly[0].Add(new IntPoint(p.x * multiplier, p.y * multiplier)); } return poly; }
/// <summary> /// Checks if polygons are intersecting /// </summary> /// <param name="p1">Subject polygon</param> /// <param name="p2">Clip polygon(s)</param> /// <returns>true if intersects</returns> public static bool IsIntersects(Paths p1, params Paths[] p2) { Clipper c = new Clipper(); Paths solution = new Paths(); c.AddPaths(p1, PolyType.ptSubject, true); for(int i = 0; i < p2.Length; i++) c.AddPaths(p2[i], PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); return solution.Count != 0; }
public static Paths ClipPolygons(List<Polygon> polygons) { var subj = new Paths(polygons.Count); var clip = new Paths(polygons.Count); foreach (var polygon in polygons) { subj.Add(polygon.ToClipperPath()); clip.Add(polygon.ToClipperPath()); } var solution = new Paths(); var c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftEvenOdd); return solution; }
public void DoCircleClipping(Vector2 pos, float radius) { ClippingPolygons subj = new ClippingPolygons(1); subj.Add(new ClippingPolygon(shape.Length)); foreach(VertexPosition point in shape){ subj[0].Add(new IntPoint((int)((point.Position.X) * accuracy), (int)((point.Position.Y) * accuracy))); } ClippingPolygons clip = new ClippingPolygons(1); clip.Add(new ClippingPolygon()); for (int alpha = 0; alpha < 360; alpha += 10) { clip[0].Add(new IntPoint((int)(((Math.Sin((alpha) * Math.PI / 180.0) * radius)+pos.X) * accuracy), (int)(((Math.Cos((alpha) * Math.PI / 180.0) * radius)+pos.Y) * accuracy))); //log.Log(pos.ToString()); } ClippingPolygons solution = new ClippingPolygons(); Clipper c = new Clipper(); c.AddPolygons(subj, PolyType.ptSubject); c.AddPolygons(clip, PolyType.ptClip); if (c.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd)) { for (int f = 0; f < solution.Count; f++) { if (f == 0) { shape = new VertexPosition[solution[f].Count]; for (int i = 0; i < solution[f].Count; i++) { shape[i] = new VertexPosition(solution[f][i].X / accuracy, solution[f][i].Y / accuracy, 0); } } } } BufferVertices(ref shape); }
private static void TestCliper() { Paths subj = new Paths(2); subj.Add(new Path(4)); subj[0].Add(new IntPoint(180, 200)); subj[0].Add(new IntPoint(260, 200)); subj[0].Add(new IntPoint(260, 150)); subj[0].Add(new IntPoint(180, 150)); subj.Add(new Path(3)); subj[1].Add(new IntPoint(215, 160)); subj[1].Add(new IntPoint(230, 190)); subj[1].Add(new IntPoint(200, 190)); Paths clip = new Paths(1); clip.Add(new Path(4)); clip[0].Add(new IntPoint(190, 210)); clip[0].Add(new IntPoint(240, 210)); clip[0].Add(new IntPoint(240, 130)); clip[0].Add(new IntPoint(190, 130)); //DrawPolygons(subj, Color.FromArgb(0x16, 0, 0, 0xFF), // Color.FromArgb(0x60, 0, 0, 0xFF)); //DrawPolygons(clip, Color.FromArgb(0x20, 0xFF, 0xFF, 0), // Color.FromArgb(0x30, 0xFF, 0, 0)); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); //DrawPolygons(solution, Color.FromArgb(0x30, 0, 0xFF, 0), // Color.FromArgb(0xFF, 0, 0x66, 0)); }
/// <summary> /// Checks if polygons are intersecting /// </summary> /// <param name="p1">Subject polygon</param> /// <param name="p2">Clip polygon(s)</param> /// <returns>true if intersects</returns> public static bool IsIntersects(Paths p1, params Paths[] p2) { var c = new Clipper(); var solution = new Paths(); c.AddPaths(p1, PolyType.ptSubject, true); foreach (Paths t in p2) c.AddPaths(t, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); return solution.Count != 0; }
private static Paths WPPolygon(Obj_AI_Hero Hero) { List<Vector2Time> HeroPath = Hero.GetWaypointsWithTime(); Vector2 myPath; Paths WPPaths = new Paths(); for (var i = 0; i < HeroPath.Count() - 1; i++) { if (HeroPath.ElementAt<Vector2Time>(i + 1).Time <= 0.6f) { Geometry.Polygon.Rectangle WPRectangle = new Geometry.Polygon.Rectangle(HeroPath.ElementAt<Vector2Time>(i).Position, HeroPath.ElementAt<Vector2Time>(i + 1).Position, Hero.BoundingRadius); Geometry.Polygon.Circle Box = new Geometry.Polygon.Circle(HeroPath.ElementAt<Vector2Time>(i).Position, Hero.BoundingRadius); WPPaths.Add(Box.ToClipperPath()); WPPaths.Add(WPRectangle.ToClipperPath()); } else { myPath = PositionAfter(Hero, 0.6f, Hero.MoveSpeed); Geometry.Polygon.Rectangle WPRectangle = new Geometry.Polygon.Rectangle(HeroPath.ElementAt<Vector2Time>(i).Position, myPath, Hero.BoundingRadius); Geometry.Polygon.Circle Box = new Geometry.Polygon.Circle(myPath, Hero.BoundingRadius); WPPaths.Add(Box.ToClipperPath()); WPPaths.Add(WPRectangle.ToClipperPath()); break; } } Geometry.Polygon.Circle WPFirstBox = new Geometry.Polygon.Circle(HeroPath.First<Vector2Time>().Position, Hero.BoundingRadius); WPPaths.Add(WPFirstBox.ToClipperPath()); return WPPaths; }
/// <summary> /// Applies a buoyant force, drag and lift to an object submerged in the water. /// </summary> /// <param name="subjectPoly"> The polygon of the object in the water.</param> /// <param name="minIndex"> The min index for a value in the "waterLinePoints" list. </param> /// <param name="maxIndex"> The max index for a value in the "waterLinePoints" list. </param> /// <param name="isIntersecting"> Are the subject and clipping polygon intersecting?. </param> private List<List<Vector2>> GetIntersectionPolygon(Vector2[] subjectPoly, int minIndex, int maxIndex, out bool isIntersecting) { Vector2 bottomHandleGlobalPos = transform.TransformPoint(water2D.handlesPosition[1]); List<List<Vector2>> intersectionPoly = new List<List<Vector2>>(); List<Vector2> clipPolygon = new List<Vector2>(); Clipper clipper = new Clipper(); Paths solutionPath = new Paths(); Path subjPath = new Path(); Path clipPath = new Path(); int len, len2, min, max; isIntersecting = true; if (surfaceVertsCount > meshSegmentsPerWaterLineSegment) { min = (int)Mathf.Floor(minIndex / meshSegmentsPerWaterLineSegment); max = (int)Mathf.Floor(maxIndex / meshSegmentsPerWaterLineSegment) + 1; if (max > waterLinePoints.Count - 2) max = waterLinePoints.Count - 2; for (int i = min; i <= max; i++) { clipPolygon.Add(waterLinePoints[i]); } int last = clipPolygon.Count - 1; clipPolygon.Add(new Vector2(clipPolygon[last].x, bottomHandleGlobalPos.y)); clipPolygon.Add(new Vector2(clipPolygon[0].x, bottomHandleGlobalPos.y)); } else { Vector2 vertGlobalPos = transform.TransformPoint(vertices[surfaceVertsCount]); clipPolygon.Add(vertGlobalPos); vertGlobalPos = transform.TransformPoint(vertices[surfaceVertsCount + surfaceVertsCount - 1]); clipPolygon.Add(new Vector2(vertGlobalPos.x, vertGlobalPos.y)); int last = clipPolygon.Count - 1; clipPolygon.Add(new Vector2(clipPolygon[last].x, bottomHandleGlobalPos.y)); clipPolygon.Add(new Vector2(clipPolygon[0].x, bottomHandleGlobalPos.y)); } if (showClippingPlolygon) { for (int i = 0; i < clipPolygon.Count; i++) { if (i < clipPolygon.Count - 1) Debug.DrawLine(clipPolygon[i], clipPolygon[i + 1], Color.green); else Debug.DrawLine(clipPolygon[i], clipPolygon[0], Color.green); } } 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; } }
/// <summary> /// Creates Paths from Polygon list for Clipper /// </summary> /// <param name="plist">Polygon</param> /// <returns>Clipper Paths of Polygons</returns> public static Paths MakePaths(params Geometry.Polygon[] plist) { var ps = new Paths(plist.Length); ps.AddRange(plist.Select(t => t.ToClipperPath())); return ps; }
private static List<List<Point>> Remove_Overlap_In_XY_Plane(List<Point> points1, List<List<Point>> otherPolygonsPoints) { var clipper = new Clipper(); clipper.StrictlySimple = true; //we only handle so-called simple polygons, this helps ensure that the only results clipper returns are simple polygons clipper.AddPath(ToClipperPath(points1), PolyType.ptSubject, true); foreach (var pointList in otherPolygonsPoints) { clipper.AddPath(ToClipperPath(pointList), PolyType.ptClip, true); } var soln = new Paths(); // clipper offers 4 operations: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm var success = clipper.Execute(ClipType.ctDifference, soln); var resultantPolygonPoints = new List<List<Point>>(); if (success.Not()) { return null; } foreach (var pointList in soln) { resultantPolygonPoints.Add(ToPoints(pointList)); } return resultantPolygonPoints; }
public static List<Vector2[]> SimplifyPolys(List<Vector2[]> polygons) { Paths paths = new Paths(); for(int i = 0; i<polygons.Count; i++){ paths.Add( Vector2ToIntList(polygons[i])); } return IntListsToVector2(ClipperLib.Clipper.SimplifyPolygons(paths)); }
// Only works if the points are in the XY plane. // Link to their Documentation: http://www.angusj.com/delphi/clipper/documentation/Docs/_Body.htm private static List<Point> Overlap_In_XY_Plane(List<Point> points1, List<Point> points2) { var clipper = new Clipper(); clipper.AddPath(ToClipperPath(points1), PolyType.ptClip, true); clipper.AddPath(ToClipperPath(points2), PolyType.ptSubject, true); var soln = new Paths(); // clipper offers 4 operations: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm var success = clipper.Execute(ClipType.ctIntersection, soln); if (success.Not()) { return null; } switch (soln.Count) { case 0: return null; case 1: return ToPoints(soln[0]); default: throw new ArgumentException("The passed polygons had multiple regions of overlap."); } }
IMoveableSection GetCutPolygon(List<Point2D> CuttingRectanglePoints) { #region GPC ////Cutting polygon //Polygon CuttingPoly = new Polygon(); //CuttingPoly.AddContour(CuttingRectanglePoints, false); ////Original polygon //Polygon OriginalPoly = new Polygon(); //OriginalPoly.AddContour(Vertices, false); //Polygon result = OriginalPoly.Clip(GpcOperation.Intersection, CuttingPoly); //GenericShape shape = new GenericShape(result); //return shape; #endregion #region Clipper Paths subj = GetPolyPaths(Vertices); Paths clip = GetPolyPaths(CuttingRectanglePoints); Paths solution = new Paths(); Clipper c = new Clipper(); c.AddPaths(subj, PolyType.ptSubject, true); c.AddPaths(clip, PolyType.ptClip, true); c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); GenericShape shape = new GenericShape(solution); return shape; #endregion }
/// <summary> /// Creates Paths from Polygon list for Clipper /// </summary> /// <param name="plist">Polygon</param> /// <returns>Clipper Paths of Polygons</returns> public static Paths MakePaths(params Geometry.Polygon[] plist) { Paths ps = new Paths(plist.Length); for (int i = 0; i < plist.Length; i++) ps.Add(plist[i].ToClipperPath()); return ps; }
private List<List<ClipperLib.IntPoint>> GetPolyPaths(List<Point2D> CuttingRectanglePoints) { int NumberOfPoints = CuttingRectanglePoints.Count; Path cutPath = new Path(NumberOfPoints); foreach (var p in CuttingRectanglePoints) { cutPath.Add(new IntPoint(p.X, p.Y)); } Paths subj = new Paths(1); subj.Add(cutPath); return subj; }