List <Point> clipPolygon(List <Point> geometry) { Clipper c = new Clipper(); var polygon = new List <IntPoint>(); foreach (var point in geometry) { polygon.Add(new IntPoint((int)point.X, (int)point.Y)); } c.AddPolygon(polygon, PolyType.ptSubject); c.AddPolygon(clipRectanglePath, PolyType.ptClip); List <List <IntPoint> > solution = new List <List <IntPoint> >(); bool success = c.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftEvenOdd); if (success && solution.Count > 0) { var result = solution.First().Select(item => new Point(item.X, item.Y)).ToList(); return(result); } return(null); }
/// <summary> /// Applies the damage to affected chunks. /// </summary> /// <param name="damage">Damage.</param> private void ApplyDamage(List <IntPoint> damage) { long minX = long.MaxValue, minY = long.MaxValue, maxX = long.MinValue, maxY = long.MinValue; for (int i = 0; i < damage.Count; ++i) { if (damage[i].X < minX) { minX = damage[i].X; } if (damage[i].X > maxX) { maxX = damage[i].X; } if (damage[i].Y < minY) { minY = damage[i].Y; } if (damage[i].Y > maxY) { maxY = damage[i].Y; } } minX = Helper.NegDivision(minX, Chunk.SIZE); maxX = Helper.NegDivision(maxX, Chunk.SIZE); minY = Helper.NegDivision(minY, Chunk.SIZE); maxY = Helper.NegDivision(maxY, Chunk.SIZE); var clipper = new Clipper(); for (int y = (int)minY; y <= maxY; ++y) { for (int x = (int)minX; x <= maxX; ++x) { var chunk = GetChunk(TerrainHelper.PackCoordinates(x, y)); clipper.Clear(); clipper.AddPolygon(new List <IntPoint>() { new IntPoint(chunk.Left, chunk.Top), new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top), new IntPoint(chunk.Left + Chunk.SIZE, chunk.Top + Chunk.SIZE), new IntPoint(chunk.Left, chunk.Top + Chunk.SIZE) }, PolyType.ptSubject); clipper.AddPolygon(damage, PolyType.ptClip); clipper.AddPolygons(chunk.Damage, PolyType.ptClip); clipper.Execute(ClipType.ctIntersection, chunk.Damage, PolyFillType.pftNonZero, PolyFillType.pftNonZero); chunk.Recalculate = true; if (ActiveChunks.Contains(chunk)) { Task.Run(() => { PlaceChunk(chunk); }); } } } }
public List <Polygon> Clip(Polygon p1, Polygon p2, OpType operation) { List <IntPoint> pol1 = new List <IntPoint>(); List <IntPoint> pol2 = new List <IntPoint>(); List <List <IntPoint> > res = new List <List <IntPoint> >(); foreach (Point point in p1.Points) { pol1.Add(new IntPoint(point.X, point.Y)); } foreach (Point point in p2.Points) { pol2.Add(new IntPoint(point.X, point.Y)); } Clipper clipper = new Clipper(); clipper.AddPolygon(pol1, PolyType.ptSubject); clipper.AddPolygon(pol2, PolyType.ptClip); switch (operation) { case OpType.Difference: clipper.Execute(ClipType.ctDifference, res); break; case OpType.Intersection: clipper.Execute(ClipType.ctIntersection, res); break; case OpType.Union: clipper.Execute(ClipType.ctUnion, res); break; case OpType.Xor: clipper.Execute(ClipType.ctXor, res); break; } List <Polygon> ret = new List <Polygon>(); foreach (var poly in res) { Polygon pol = new Polygon() { Points = new List <Point>() }; foreach (var poi in poly) { pol.Points.Add(new Point() { X = poi.X, Y = poi.Y }); } ret.Add(pol); } return(ret); }
double Intersection(List <IntPoint> polygon, Municipality municipality) { Clipper c = new Clipper(); c.AddPolygon(polygon, PolyType.ptSubject); c.AddPolygon(municipality.polygon, PolyType.ptClip); List <List <IntPoint> > solution = new List <List <IntPoint> >(); c.Execute(ClipType.ctIntersection, solution); return(solution.Sum(s => Clipper.Area(s))); }
void UpdateFrontPolygon(Polygon surface, Polygon tunnel) { frontPolygons.Clear(); //Lets generate the polygons which represent the landscape. //Clipper c = new Clipper(); clipper.AddPolygon(surface, PolyType.Subject); clipper.AddPolygon(tunnel, PolyType.Clip); bool result = clipper.Execute(ClipType.Difference, frontPolygons, PolyFillType.EvenOdd, PolyFillType.EvenOdd); clipper.Clear(); }
// 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); }
private void RemoveCircle(Vector2 center, float radius, int count = 40) { List <IntPoint> poly = new List <IntPoint>(); float delta = Mathf.PI * 2 / count; for (int i = 0; i < count; i++) { float x = center.x + Mathf.Cos(delta * i) * radius; float y = center.y + Mathf.Sin(delta * i) * radius; poly.Add(Convert(x, y)); } Clipper clipper = new Clipper(Clipper.ioStrictlySimple); clipper.AddPolygons(m_polys, PolyType.ptSubject); clipper.AddPolygon(poly, PolyType.ptClip); clipper.Execute(ClipType.ctDifference, m_polyTree); Clipper.PolyTreeToPolygons(m_polyTree, m_polys); Clipper.SimplifyPolygons(m_polys); List <DelaunayTriangle> triangles = GenerateTriangles(); GenerateMesh(triangles); }
private static void CleanUpSolution(Polygons solution, double delta) { Clipper clpr = new Clipper(); clpr.AddPolygons(solution, PolyType.Subject); if (delta > 0) { clpr.Execute(ClipType.Union, solution, PolyFillType.Positive, PolyFillType.Positive); } else { RectangleL r = clpr.GetBounds(); Polygon outer = new Polygon(4); outer.Add(new Vector2(r.left - 10, r.bottom + 10)); outer.Add(new Vector2(r.right + 10, r.bottom + 10)); outer.Add(new Vector2(r.right + 10, r.top - 10)); outer.Add(new Vector2(r.left - 10, r.top - 10)); clpr.AddPolygon(outer, PolyType.Subject); clpr.Execute(ClipType.Union, solution, PolyFillType.Negative, PolyFillType.Negative); if (solution.Count > 0) { solution.RemoveAt(0); for (int i = 0; i < solution.Count; i++) { solution[i].Reverse(); } } } }
/// <summary> /// Determines if the two polygons overlap. /// Polygons that touch at a vertex or along an edge are considered overlapping. /// </summary> public static bool OverlappingPolygons(string polygonWkt1, string polygonWkt2) { //Note: the clipper library uses 2D geometry while we have spherical coordinates. But it should be near enough for our purposes. var points1 = ConvertAndValidatePolygon(polygonWkt1); var points2 = ConvertAndValidatePolygon(polygonWkt2); //Simple bounding box check first. if (!BoundingBoxesOverlap(points1, points2)) { return(false); } // The clipper library doesn't work as expected for touching polygons so check. // Check both ways as a vertex of one polygon may be touching an edge of the other. foreach (var point in points1) { if (PointOnPolygonEdge(points2, point.X, point.Y)) { return(true); } } foreach (var point in points2) { if (PointOnPolygonEdge(points1, point.X, point.Y)) { return(true); } } // Now do the clipper polygon intersection check. var polygon1 = ClipperPolygon(points1); var polygon2 = ClipperPolygon(points2); var clipper = new Clipper(); clipper.AddPolygon(polygon1, PolyType.ptSubject); clipper.AddPolygon(polygon2, PolyType.ptClip); var intersectingPolygons = new List <List <IntPoint> >(); var succeeded = clipper.Execute(ClipType.ctIntersection, intersectingPolygons); return(succeeded && intersectingPolygons.Count > 0); }
/// <summary> /// Inverts the selection. /// </summary> /// <param name="surface"> /// Surface for the selection path. /// </param> /// <param name='imageSize'> /// The size of the document. /// </param> public void Invert(Surface surface, Gdk.Size imageSize) { List <List <IntPoint> > resultingPolygons = new List <List <IntPoint> > (); var documentPolygon = CreateRectanglePolygon(new Rectangle(0, 0, imageSize.Width, imageSize.Height)); // Create a rectangle that is the size of the entire image, // and subtract all of the polygons in the current selection from it. SelectionClipper.AddPolygon(documentPolygon, PolyType.ptSubject); SelectionClipper.AddPolygons(SelectionPolygons, PolyType.ptClip); SelectionClipper.Execute(ClipType.ctDifference, resultingPolygons); SelectionClipper.Clear(); SelectionPolygons = resultingPolygons; MarkDirty(); }
static public PolyTree FindDistictObjectBounds(ImageBuffer image) { MarchingSquaresByte marchingSquaresData = new MarchingSquaresByte(image, 5, 0); marchingSquaresData.CreateLineSegments(); Polygons lineLoops = marchingSquaresData.CreateLineLoops(1); if (lineLoops.Count == 1) { return(null); } // create a bounding polygon to clip against IntPoint min = new IntPoint(long.MaxValue, long.MaxValue); IntPoint max = new IntPoint(long.MinValue, long.MinValue); foreach (Polygon polygon in lineLoops) { 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); } } Polygon 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 Clipper clipper = new Clipper(); clipper.AddPolygons(lineLoops, PolyType.ptSubject); clipper.AddPolygon(boundingPoly, PolyType.ptClip); PolyTree polyTreeForPlate = new PolyTree(); clipper.Execute(ClipType.ctIntersection, polyTreeForPlate); return(polyTreeForPlate); }
public void RectangularFillBetweenPolygons(ClipPaths paths, double cuttingdepth, double rapiddepth, double ystep, double x1, double x2, double y1, double y2, double stepdown) { ClipPaths clips = paths; // ClipPaths paths = new ClipPaths(); ClipperLib.Clipper cp = new Clipper(); //cp.add cp.AddPolygons(paths, PolyType.ptClip); for(double y = y1;y<y2;y+= ystep * 2) { ClipPath p = new ClipPath(); p.Add(new IntPoint() { X = (int)(x1 * 100000), Y = (int)(y * 100000) }); p.Add(new IntPoint() { X = (int)(x2 * 100000), Y = (int)(y * 100000) }); p.Add(new IntPoint() { X = (int)(x2 * 100000), Y = (int)((y+ystep) * 100000) }); p.Add(new IntPoint() { X = (int)(x1 * 100000), Y = (int)((y + ystep) * 100000) }); cp.AddPolygon(p, PolyType.ptSubject); } ClipPaths res = new ClipPaths(); cp.Execute(ClipType.ctDifference, res); AddClipperPolygonsToCarve(res, cuttingdepth, rapiddepth, stepdown); }
public void GenerateMesh() { if (cornerNodeLists == null) { return; } if (cornerNodeLists.Count == 0) { return; } List <roadNetworkIntersection> cornerNodes = cornerNodeLists[0]; if (cornerNodes.Count < 3) { return; //it's just too damn small. } vertices.Clear(); faces.Clear(); uvs.Clear(); Vector3 center = new Vector3(); foreach (roadNetworkIntersection node in cornerNodes) { center += node.gameObject.transform.position; } center /= cornerNodes.Count; gameObject.transform.position = center; Clipper clipper = new Clipper(); foreach (List <roadNetworkIntersection> wayList in cornerNodeLists) { List <IntPoint> contour = new List <IntPoint>(); foreach (roadNetworkIntersection corner in wayList) { contour.Add(new IntPoint((long)((corner.transform.position - center).x * floatMultiplier), (long)((corner.transform.position - center).z * floatMultiplier))); } clipper.AddPolygon(contour, PolyType.ptSubject); } if (HoleNodeLists != null) { foreach (List <roadNetworkIntersection> wayList in HoleNodeLists) { if (wayList != null) { List <IntPoint> contour = new List <IntPoint>(); foreach (roadNetworkIntersection corner in wayList) { contour.Add(new IntPoint((long)((corner.transform.position - center).x * floatMultiplier), (long)((corner.transform.position - center).z * floatMultiplier))); } clipper.AddPolygon(contour, PolyType.ptClip); } } } clipper.ForceSimple = true; PolyTree polyTree = new PolyTree(); clipper.Execute(ClipType.ctDifference, polyTree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); foreach (PolyNode polyNode in polyTree.Childs) { MakeSection(vertices, faces, polyNode); } // //faces = new List<int>(triangulator.Triangulate()); // // int capVerts = vertices2d.Count; // //// for(int i = 0; i < capVerts; i++) { //// vertices.Add (new Vector3((float)vertices2d[i].Y, height, (float)vertices2d[i].Y)); //// } // // if(height > 0.001f) { // double runningTotal = 0.0; // for(int i = 0; i < vertices2d.Count; i++){ // int j = i+1; // if(j >= vertices2d.Count) j = 0; // runningTotal += ((vertices2d[j].X - vertices2d[i].X) * (vertices2d[j].Y + vertices2d[i].Y)); // } // int start = 0; // int end = capVerts; // int step = 1; // if(runningTotal <= 0) { // start = capVerts-1; // end = -1; // step = -1; // } // } //proper UVs will need to be made, this is just for testing foreach (Vector3 vertex in vertices) { Vector2 uvert = new Vector2(); uvert.x = vertex.x / 3; uvert.y = vertex.z / 3; uvs.Add(uvert); } MeshFilter mf = GetComponent <MeshFilter>(); Mesh mesh = new Mesh(); mf.mesh = mesh; mesh.vertices = vertices.ToArray(); mesh.triangles = faces.ToArray(); mesh.uv = uvs.ToArray(); if (vertices.Count > 0) { mesh.RecalculateNormals(); mesh.RecalculateBounds(); } }
/// <summary> /// Generate chunk data for a given chunk. /// </summary> /// <param name="chunk">Chunk.</param> public void GenerateChunk(Chunk chunk) { if (chunk.State != ChunkStateEnum.Emtpy) { return; } long top = chunk.Top, left = chunk.Left; var clipper = new Clipper(); chunk.Polygons = new List <List <IntPoint> >(); // Add chunk bounding rectangle clipper.AddPolygon(new List <IntPoint>() { new IntPoint(left, top), new IntPoint(left + Chunk.SIZE, top), new IntPoint(left + Chunk.SIZE, top + Chunk.SIZE), new IntPoint(left, top + Chunk.SIZE) }, PolyType.ptSubject); List <IntPoint> surfacePolygon = new List <IntPoint>(Chunk.SIZE / SPACING + 3); for (int i = 0; i <= Chunk.SIZE / SPACING; ++i) { surfacePolygon.Add(new IntPoint(left + i * SPACING, (int)HeightMap(left + i * SPACING))); } surfacePolygon.Add(new IntPoint(left + Chunk.SIZE, top + Chunk.SIZE)); surfacePolygon.Add(new IntPoint(left, top + Chunk.SIZE)); clipper.AddPolygon(surfacePolygon, PolyType.ptClip); // Check midpoint for surface { var midpoint = HeightMap(left + Chunk.SIZE / 2); chunk.IsSurface = midpoint >= top && midpoint <= top + Chunk.SIZE; } // Add solution to chunk data clipper.Execute(ClipType.ctIntersection, chunk.Polygons, PolyFillType.pftNonZero, PolyFillType.pftNonZero); // Cave generation chunk.Cavities = new List <List <IntPoint> >(); for (int i = 0; i < Chunk.SIZE / SPACING; ++i) { var x = left + SPACING / 2 + i * SPACING; var y = HeightMap(x) + 4; if (chunk.ContainsHeight(y)) { chunk.GrassPoints.Add(new Chunk.GrassPoint() { Position = new Vector2(x, y), Rotation = MathHelper.PiOver2 - Helper.DirectionToAngle(Normal(x)) }); } } chunk.Recalculate = true; chunk.State = ChunkStateEnum.Generated; }