Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 4
0
        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)));
        }
Ejemplo n.º 5
0
    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();
    }
Ejemplo n.º 6
0
        // 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);
        }
Ejemplo n.º 7
0
    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);
    }
Ejemplo n.º 8
0
            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();
                        }
                    }
                }
            }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
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();
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
    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();
        }
    }
Ejemplo n.º 14
0
        /// <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;
        }