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;
    }
Example #2
0
        /// <summary>
        ///  Conduct a clip operation on this profile.
        /// </summary>
        internal void Clip(IEnumerable <Profile> additionalHoles = null, double tolerance = Vector3.EPSILON)
        {
            var clipper = new ClipperLib.Clipper();

            clipper.AddPath(this.Perimeter.ToClipperPath(tolerance), ClipperLib.PolyType.ptSubject, true);
            if (this.Voids != null)
            {
                clipper.AddPaths(this.Voids.Select(p => p.ToClipperPath(tolerance)).ToList(), ClipperLib.PolyType.ptClip, true);
            }
            if (additionalHoles != null)
            {
                clipper.AddPaths(additionalHoles.Select(h => h.Perimeter.ToClipperPath(tolerance)).ToList(), ClipperLib.PolyType.ptClip, true);
            }
            var solution = new List <List <ClipperLib.IntPoint> >();
            var result   = clipper.Execute(ClipperLib.ClipType.ctDifference, solution, ClipperLib.PolyFillType.pftEvenOdd);

            // Completely disjoint polygons like a circular pipe
            // profile will result in an empty solution.
            if (solution.Count > 0)
            {
                var polys = solution.Select(s => s.ToPolygon(tolerance)).ToArray();
                this.Perimeter = polys[0];
                this.Voids     = polys.Skip(1).ToArray();
            }
        }
    //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);
    }
Example #4
0
    public static XYPolygon GetIntersection(XYPolygon pol1, XYPolygon pol2)
    {



      List<List<IntPoint>> subj = new List<List<IntPoint>>();
  subj.Add(new List<IntPoint>(pol1.Points.Count));
      foreach(var p in pol1.Points)
        subj[0].Add(new IntPoint(p.X, p.Y));


      List<List<IntPoint>> clip = new List<List<IntPoint>>();
      clip.Add(new List<IntPoint>(pol2.Points.Count));
  foreach (var p in pol2.Points)
    clip[0].Add(new IntPoint(p.X, p.Y));


  List<List<IntPoint>> solution = new List<List<IntPoint>>();

	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);

  XYPolygon ToReturn = new XYPolygon();
  if (solution.Count > 0) 
  foreach (var p in solution[0])
    ToReturn.Points.Add(new XYPoint(p.X,p.Y));

          return ToReturn;
    }
Example #5
0
        private double ClippedArea()
        {
            if (this.Voids == null || this.Voids.Count == 0)
            {
                return(this.Perimeter.Area());
            }

            var clipper = new ClipperLib.Clipper();
            var normal  = Perimeter.Normal();

            if (normal.IsAlmostEqualTo(Vector3.ZAxis))
            {
                clipper.AddPath(Perimeter.ToClipperPath(), ClipperLib.PolyType.ptSubject, true);
                clipper.AddPaths(this.Voids.Select(p => p.ToClipperPath()).ToList(), ClipperLib.PolyType.ptClip, true);
            }
            else
            {
                var transform = new Transform(Perimeter.Start, normal);
                transform.Invert();
                var perimeter = Perimeter.TransformedPolygon(transform);
                clipper.AddPath(perimeter.ToClipperPath(), ClipperLib.PolyType.ptSubject, true);
                clipper.AddPaths(this.Voids.Select(p => p.TransformedPolygon(transform).ToClipperPath()).ToList(), ClipperLib.PolyType.ptClip, true);
            }

            var solution = new List <List <ClipperLib.IntPoint> >();

            clipper.Execute(ClipperLib.ClipType.ctDifference, solution, ClipperLib.PolyFillType.pftEvenOdd);
            return(solution.Sum(s => ClipperLib.Clipper.Area(s)) / Math.Pow(1.0 / Vector3.EPSILON, 2));
        }
Example #6
0
 public List<List<IntPoint>> Run (List<List<IntPoint>> subject, double scale)
 {
   var c = ToClipper (scale, clip);
   var clipper = new Clipper ();
   clipper.AddPaths (subject, PolyType.ptSubject, subjectClosed);
   clipper.AddPaths (c, PolyType.ptClip, true);
   var solution = new List<List<IntPoint>> ();
   clipper.Execute (type, solution, subjectFill, clipFill);
   return solution;
 }
            public double FitnessFunctionG()
            {
                // return 3;
                double fitnessFunctionVar = 0;
                int    precision          = 100;

                Clipper cc = new ClipperLib.Clipper();

                Paths solution = new Paths();
                Paths subjects = new Paths();
                Paths clips    = new Paths();



                foreach (Room room in collection)
                {
                    subjects.Add(new Path(room.GetClipperLibPath(precision)));
                }

                IntPoint boundaryA = new IntPoint(
                    (int)((boundary.GetBoundingBox(false).Center.X - boundary.GetBoundingBox(false).Diagonal.X / 2) * precision)
                    , (int)((boundary.GetBoundingBox(false).Center.Y - boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision));

                IntPoint boundaryB = new IntPoint(
                    (int)((boundary.GetBoundingBox(false).Center.X - boundary.GetBoundingBox(false).Diagonal.X / 2) * precision)
                    , (int)((boundary.GetBoundingBox(false).Center.Y + boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision));

                IntPoint boundaryC = new IntPoint(
                    (int)((boundary.GetBoundingBox(false).Center.X + boundary.GetBoundingBox(false).Diagonal.X / 2) * precision)
                    , (int)((boundary.GetBoundingBox(false).Center.Y + boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision));

                IntPoint boundaryD = new IntPoint(
                    (int)((boundary.GetBoundingBox(false).Center.X + boundary.GetBoundingBox(false).Diagonal.X / 2) * precision)
                    , (int)((boundary.GetBoundingBox(false).Center.Y - boundary.GetBoundingBox(false).Diagonal.Y / 2) * precision));


                clips.Add(new Path(new List <IntPoint>()
                {
                    boundaryA, boundaryB, boundaryC, boundaryD
                }));

                cc.AddPaths(subjects, PolyType.ptSubject, true);
                cc.AddPaths(clips, PolyType.ptClip, true);


                cc.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                foreach (Path path in solution)
                {
                    fitnessFunctionVar += Clipper.Area(path);
                }


                return(fitnessFunctionVar);
            }
Example #8
0
 public double RelativeAreaDiff (List<List<IntPoint>> actual, List<List<IntPoint>>expected)
 {
   var expectedArea = expected.Sum (path => Clipper.Area (path));
   var difference = new List<List<IntPoint>> ();
   var clipper = new Clipper ();
   clipper.AddPaths (actual, PolyType.ptSubject, true);
   clipper.AddPaths (expected, PolyType.ptClip, true);
   clipper.Execute (ClipType.ctXor, difference, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);
   var differenceArea = difference.Sum (path => Clipper.Area (path));
   return Math.Abs (differenceArea) / Math.Abs (expectedArea);
 }
        /// <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;
        }
Example #10
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 static List<Vector2> Add(this Shape shape, Shape secondShape, Action<Shape> completed)
        {
            List<Vector2> points = new List<Vector2>();

            Clipper c = new Clipper();

            List<List<IntPoint>> subj = new List<List<IntPoint>>();
            List<List<IntPoint>> clip = new List<List<IntPoint>>();
            List<List<IntPoint>> solution = new List<List<IntPoint>>();
            List<IntPoint> p1 = new List<IntPoint>();
            List<IntPoint> p2 = new List<IntPoint>();
            int i = 0, l = shape.Points.Length;
            Vector2 pos = shape.BuiltGameObject.transform.position;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(shape.Points[i].x + pos.x,shape.Points[i].y + pos.y);
                p1.Add(ip);
            }
            p1.Add(p1[0]);

            pos = secondShape.BuiltGameObject.transform.position;
            i = 0; l = secondShape.Points.Length;
            for(;i<l;++i)
            {
                IntPoint ip = new IntPoint(secondShape.Points[i].x + pos.x,secondShape.Points[i].y + pos.y);
                p2.Add(ip);
            }
            p2.Add(p2[0]);

            subj.Add(p1);
            clip.Add(p2);

            c.AddPaths(subj,PolyType.ptSubject,true);
            c.AddPaths(clip,PolyType.ptClip,true);
            c.Execute(ClipType.ctUnion,solution);

            i = 0; l = solution[0].Count;
            for(;i<l;++i)
            {
                float x = System.Convert.ToSingle(solution[0][i].X);
                float y = System.Convert.ToSingle(solution[0][i].Y);
                points.Add(new Vector2(x,y));
            }

            Mesh2D.Instance.ReBuild(shape.BuiltGameObject,points,completed,shape.Col);
            return points;
        }
Example #12
0
		private PathStorage CombinePaths(IVertexSource a, IVertexSource b, ClipType clipType)
		{
			List<List<IntPoint>> aPolys = VertexSourceToClipperPolygons.CreatePolygons(a);
			List<List<IntPoint>> bPolys = VertexSourceToClipperPolygons.CreatePolygons(b);

			Clipper clipper = new Clipper();

			clipper.AddPaths(aPolys, PolyType.ptSubject, true);
			clipper.AddPaths(bPolys, PolyType.ptClip, true);

			List<List<IntPoint>> intersectedPolys = new List<List<IntPoint>>();
			clipper.Execute(clipType, intersectedPolys);

			PathStorage output = VertexSourceToClipperPolygons.CreatePathStorage(intersectedPolys);

			output.Add(0, 0, ShapePath.FlagsAndCommand.CommandStop);

			return output;
		}
Example #13
0
    List<IntPoint> GetArea(Mesh mesh)
    {
        int[] triangles = mesh.triangles;
        Vector3[] vertices = mesh.vertices;

        List<Vector2> list = new List<Vector2>();

        //Debug.Log("ver count: " + vertices.Length + " triangle: " + triangles.Length);

        float y = float.MinValue;
        for(int i=0; i < triangles.Length; i = i+3){
            Vector3 p0 = vertices[triangles[i]];
            Vector3 p1 = vertices[triangles[i+1]];
            Vector3 p2 = vertices[triangles[i+2]];

            if(Approximately(p0.y, p1.y) && Approximately(p0.y, p2.y)){
                //Debug.Log(string.Format("({0}, {1}, {2})", p0, p1, p2));

                if(y == float.MinValue){
                    y = p0.y;
                }

                if(Approximately(p0.y, y)){
                    list.Add(new Vector2(p0.x, p0.z));
                    list.Add(new Vector2(p1.x, p1.z));
                    list.Add(new Vector2(p2.x, p2.z));
                }
            }
        }

        //Debug.Log("list: " + list.Count);

        List<List<IntPoint>> paths = new List<List<IntPoint>>();
        for(int i=0; i < list.Count; i = i+3){
            List<IntPoint> path = new List<IntPoint>();

            for(int j=0; j < 3; j++){
                path.Add(new IntPoint(list[i+j].x * clipScalling, list[i+j].y * clipScalling));
            }

            paths.Add(path);
        }

        Clipper clipper = new Clipper();

        List<List<IntPoint>> solution = new List<List<IntPoint>>();
        clipper.AddPaths(paths, PolyType.ptSubject, true);
        clipper.Execute(ClipType.ctUnion, solution);

        if(solution.Count > 0){
            return solution[0];
        }

        return null;
    }
Example #14
0
        /// <summary>
        /// Perform a union operation, returning a new profile that is the union of the current profile with the other profile
        /// <param name="profile">The profile with which to create a union.</param>
        /// <param name="tolerance">An optional tolerance.</param>
        /// </summary>
        public Profile Union(Profile profile, double tolerance = Vector3.EPSILON)
        {
            var clipper = new ClipperLib.Clipper();

            clipper.AddPath(this.Perimeter.ToClipperPath(tolerance), PolyType.ptSubject, true);
            clipper.AddPath(profile.Perimeter.ToClipperPath(tolerance), PolyType.ptClip, true);

            if (this.Voids != null && this.Voids.Count > 0)
            {
                clipper.AddPaths(this.Voids.Select(v => v.ToClipperPath(tolerance)).ToList(), PolyType.ptSubject, true);
            }
            if (profile.Voids != null && profile.Voids.Count > 0)
            {
                clipper.AddPaths(profile.Voids.Select(v => v.ToClipperPath(tolerance)).ToList(), PolyType.ptClip, true);
            }
            var solution = new List <List <ClipperLib.IntPoint> >();

            clipper.Execute(ClipType.ctUnion, solution);
            return(new Profile(solution.Select(s => s.ToPolygon(tolerance)).ToList()));
        }
Example #15
0
		public static void GenerateLinePaths(Polygons polygonToInfill, ref Polygons infillLinesToPrint, int lineSpacing, int infillExtendIntoPerimeter_um, double rotation, long rotationOffset = 0)
		{
			if (polygonToInfill.Count > 0)
			{
				Polygons outlines = polygonToInfill.Offset(infillExtendIntoPerimeter_um);
				if (outlines.Count > 0)
				{
					PointMatrix matrix = new PointMatrix(-(rotation + 90)); // we are rotating the part so we rotate by the negative so the lines go the way we expect

					outlines.ApplyMatrix(matrix);

					Aabb boundary = new Aabb(outlines);

					boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing - rotationOffset;
					int xLineCount = (int)((boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing);
					Polygons unclipedPatern = new Polygons();

					long firstX = boundary.min.X / lineSpacing * lineSpacing;
					for (int lineIndex = 0; lineIndex < xLineCount; lineIndex++)
					{
						Polygon line = new Polygon();
						line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.min.Y));
						line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.max.Y));
						unclipedPatern.Add(line);
					}

					PolyTree ret = new PolyTree();
					Clipper clipper = new Clipper();
					clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
					clipper.AddPaths(outlines, PolyType.ptClip, true);
					clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

					Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret);
					PointMatrix inversematrix = new PointMatrix((rotation + 90));
					newSegments.ApplyMatrix(inversematrix);

					infillLinesToPrint.AddRange(newSegments);
				}
			}
		}
Example #16
0
        public void OriginalClipperFileBasedTest()
        {
            var testData = LoadTestHelper.LoadFromFile("TestData/tests.txt");

            foreach (var test in testData.Values)
            {
                var subjects = test.Subjects.ToOriginal();
                var clips    = test.Clips.ToOriginal();

                var clipper = new ClipperLib.Clipper();
                clipper.AddPaths(subjects, PolyType.ptSubject, true);
                clipper.AddPaths(clips, PolyType.ptClip, true);

                var originalSolution = new List <List <ClipperLib.IntPoint> >();
                var clipType         = (ClipType)Enum.Parse(typeof(ClipType), $"ct{test.ClipOperation}", true);
                var fillType         = (PolyFillType)Enum.Parse(typeof(PolyFillType), $"pft{test.FillType}", true);
                Assert.IsTrue(clipper.Execute(clipType, originalSolution, fillType));
                Assert.AreEqual(test.Solution.Count, originalSolution.Count, test.Caption);

                var solution = originalSolution.ToNew();

                // TODO: reinclude these tests once test data is verified.
                var ignoreTestNumbers = new[] { 36, 38, 39, 44, 46, 48, 51, 52, 59, 64, 67, 69 };
                if (ignoreTestNumbers.Contains(test.TestNumber))
                {
                    continue;
                }

                Assert.AreEqual(test.Solution.Count, solution.Count, $"{test.TestNumber}: {test.Caption}");

                // Match points, THIS IS DESTRUCTIVE TO BOTH THE TEST DATA AND RESULT DATA.
                Assert.IsTrue(AreSame(test, solution));

                // If we had an exact match then both solutions should now be empty.
                Assert.AreEqual(0, test.Solution.Count, $"{test.TestNumber}: {test.Caption}");
                Assert.AreEqual(0, solution.Count, $"{test.TestNumber}: {test.Caption}");
            }
        }
Example #17
0
		private PathStorage CombinePaths(IVertexSource a, IVertexSource b, ClipType clipType)
		{
			List<List<IntPoint>> aPolys = CreatePolygons(a);
			List<List<IntPoint>> bPolys = CreatePolygons(b);

			Clipper clipper = new Clipper();

			clipper.AddPaths(aPolys, PolyType.ptSubject, true);
			clipper.AddPaths(bPolys, PolyType.ptClip, true);

			List<List<IntPoint>> intersectedPolys = new List<List<IntPoint>>();
			clipper.Execute(clipType, intersectedPolys);

			PathStorage output = new PathStorage();

			foreach (List<IntPoint> polygon in intersectedPolys)
			{
				bool first = true;
				foreach (IntPoint point in polygon)
				{
					if (first)
					{
						output.Add(point.X / 1000.0, point.Y / 1000.0, ShapePath.FlagsAndCommand.CommandMoveTo);
						first = false;
					}
					else
					{
						output.Add(point.X / 1000.0, point.Y / 1000.0, ShapePath.FlagsAndCommand.CommandLineTo);
					}
				}

				output.ClosePolygon();
			}

			output.Add(0, 0, ShapePath.FlagsAndCommand.CommandStop);

			return output;
		}
Example #18
0
        private double ClippedArea()
        {
            if (this.Voids == null || this.Voids.Count == 0)
            {
                return(this.Perimeter.Area());
            }

            var clipper = new ClipperLib.Clipper();

            clipper.AddPath(this.Perimeter.ToClipperPath(), ClipperLib.PolyType.ptSubject, true);
            clipper.AddPaths(this.Voids.Select(p => p.ToClipperPath()).ToList(), ClipperLib.PolyType.ptClip, true);
            var solution = new List <List <ClipperLib.IntPoint> >();

            clipper.Execute(ClipperLib.ClipType.ctDifference, solution, ClipperLib.PolyFillType.pftEvenOdd);
            return(solution.Sum(s => ClipperLib.Clipper.Area(s)) / Math.Pow(1.0 / Vector3.EPSILON, 2));
        }
Example #19
0
        public void Clip(double x0, double x1, double y0, double y1)
        {
            var p00 = new Point3d(x0, y0, 0.0);
            var p01 = new Point3d(x0, y1, 0.0);
            var p11 = new Point3d(x1, y1, 0.0);
            var p10 = new Point3d(x1, y0, 0.0);

            var clip = new[] { p00, p10, p11, p01, p00 }.ToPolygon(Plane.WorldXY, Unit);

            var clipper = new Clipper();

            clipper.AddPaths(Polygons, PolyType.ptSubject, true);
            clipper.AddPath(clip, PolyType.ptClip, true);

            var solution = new List<List<IntPoint>>();

            clipper.Execute(ClipType.ctIntersection, solution, PolyFillType.pftEvenOdd, PolyFillType.pftNonZero);

            Polygons = solution;
            Curves = Polygons.ToCurves(Plane, Unit);
        }
Example #20
0
        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));
        }
Example #21
0
		public static List<Polygons> ProcessIntoSeparatIslands(this Polygons polygons)
		{
			List<Polygons> ret = new List<Polygons>();
			Clipper clipper = new Clipper();
			PolyTree resultPolyTree = new PolyTree();
			clipper.AddPaths(polygons, PolyType.ptSubject, true);
			clipper.Execute(ClipType.ctUnion, resultPolyTree);

			polygons.ProcessPolyTreeNodeIntoSeparatIslands(resultPolyTree, ret);
			return ret;
		}
Example #22
0
		public static Polygons CreateLineIntersections(this Polygons polygons, Polygons other)
		{
			Clipper clipper = new Clipper();

			clipper.AddPaths(other, PolyType.ptSubject, false);
			clipper.AddPaths(polygons, PolyType.ptClip, true);

			PolyTree clippedLines = new PolyTree();

			clipper.Execute(ClipType.ctIntersection, clippedLines);

			return Clipper.OpenPathsFromPolyTree(clippedLines);
		}
Example #23
0
		public static Polygons CreateIntersection(this Polygons polygons, Polygons other)
		{
			Polygons ret = new Polygons();
			Clipper clipper = new Clipper();
			clipper.AddPaths(polygons, PolyType.ptSubject, true);
			clipper.AddPaths(other, PolyType.ptClip, true);
			clipper.Execute(ClipType.ctIntersection, ret);
			return ret;
		}
Example #24
0
        public JsonResult GetBySponsor(ObjectId id)
        {
            var spots = Context.SponsorSpots.GetSpotsBySponsors(id);

            Clipper clipper = new Clipper();
            var polygons = new List<List<IntPoint>>();
            var scale = 100000000.0;

            foreach (var spot in spots)
            {
                var polygon = new List<IntPoint>();

                foreach (var coord in spot.SpotShape)
                {
                    polygon.Add(new IntPoint(coord.Longitude * scale, coord.Latitude * scale));
                }
                polygons.Add(polygon);
            }

            var solution = new List<List<IntPoint>>();

            clipper.AddPaths(polygons, PolyType.ptSubject, true);
            clipper.Execute(ClipType.ctUnion, solution,
                PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            var results = new List<Spot>();

            foreach (var shape in solution)
            {
                var resultShape = new Spot();
                foreach (var item in shape)
                {
                    resultShape.SpotShape.Add(new Coordinate { Latitude = item.Y / scale, Longitude = item.X / scale });
                }
                results.Add(resultShape);
            }

            return Json(new { success = true, results = results }, JsonRequestBehavior.AllowGet);
        }
Example #25
0
        /// <summary>
        ///     Joins all the polygones in the list in one polygone if they interect.
        /// </summary>
        /// <param name="sList">The polygon list.</param>
        /// <returns></returns>
        public static List<Polygon> ELJoinPolygons(this List<Polygon> sList)
        {
            var p = ELClipPolygons(sList);
            var tList = new List<List<IntPoint>>();

            var c = new Clipper();
            c.AddPaths(p, PolyType.ptClip, true);
            c.Execute(ClipType.ctUnion, tList, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            return ToPolygons(tList);
        }
Example #26
0
		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;
		}
Example #27
0
        ////////////////////////////////////////////////
        
        static void Main(string[] args)
        {
          ////quick test with random polygons ...
          //Paths ss = new Paths(1), cc = new Paths(1), sss = new Paths();
          //Random r = new Random((int)DateTime.Now.Ticks);
          //int scale = 1000000000; //tests 128bit math
          //ss.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
          //cc.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
          //Clipper cpr = new Clipper();
          //cpr.AddPaths(ss, PolyType.ptSubject, true);
          //cpr.AddPaths(cc, PolyType.ptClip, true);
          //cpr.Execute(ClipType.ctUnion, sss, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
          //sss = Clipper.OffsetPolygons(sss, -5.0 * scale, JoinType.jtMiter, 4);
          //SVGBuilder svg1 = new SVGBuilder();
          //svg1.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
          //svg1.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda);
          //svg1.AddPaths(ss);
          //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
          //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a);
          //svg1.AddPaths(cc);
          //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
          //svg1.style.penClr = Color.FromArgb(0, 0x33, 0);
          //svg1.AddPaths(sss);
          //svg1.SaveToFile("solution.svg", 1.0 / scale);
          //return;

          if (args.Length < 5)
            {
                string appname = System.Environment.GetCommandLineArgs()[0];
                appname = System.IO.Path.GetFileName(appname);
                Console.WriteLine("");
                Console.WriteLine("Usage:");
                Console.WriteLine("  {0} CLIPTYPE s_file c_file INPUT_DEC_PLACES SVG_SCALE [S_FILL, C_FILL]", appname);
                Console.WriteLine("  where ...");
                Console.WriteLine("  CLIPTYPE = INTERSECTION|UNION|DIFFERENCE|XOR");
                Console.WriteLine("  FILLMODE = NONZERO|EVENODD");
                Console.WriteLine("  INPUT_DEC_PLACES = signific. decimal places for subject & clip coords.");
                Console.WriteLine("  SVG_SCALE = scale of SVG image as power of 10. (Fractions are accepted.)");
                Console.WriteLine("  both S_FILL and C_FILL are optional. The default is EVENODD.");
                Console.WriteLine("Example:");
                Console.WriteLine("  Intersect polygons, rnd to 4 dec places, SVG is 1/100 normal size ...");
                Console.WriteLine("  {0} INTERSECTION subj.txt clip.txt 0 0 NONZERO NONZERO", appname);
                return;
            }

            ClipType ct;
            switch (args[0].ToUpper())
            {
                case "INTERSECTION": ct = ClipType.ctIntersection; break;
                case "UNION": ct = ClipType.ctUnion; break;
                case "DIFFERENCE": ct = ClipType.ctDifference; break;
                case "XOR": ct = ClipType.ctXor; break;
                default: Console.WriteLine("Error: invalid operation - {0}", args[0]); return;
            }

            string subjFilename = args[1];
            string clipFilename = args[2];
            if (!File.Exists(subjFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", subjFilename);
                return;
            }
            if (!File.Exists(clipFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", clipFilename);
                return;
            }

            int decimal_places = 0;
            if (!Int32.TryParse(args[3], out decimal_places))
            {
                Console.WriteLine("Error: invalid number of decimal places - {0}", args[3]);
                return;
            }
            if (decimal_places > 8) decimal_places = 8;
            else if (decimal_places < 0) decimal_places = 0;

            double svg_scale = 0;
            if (!double.TryParse(args[4], out svg_scale))
            {
                Console.WriteLine("Error: invalid value for SVG_SCALE - {0}", args[4]);
                return;
            }
            if (svg_scale < -18) svg_scale = -18;
            else if (svg_scale > 18) svg_scale = 18;
            svg_scale = Math.Pow(10, svg_scale - decimal_places);//nb: also compensate for decimal places


            PolyFillType pftSubj = PolyFillType.pftEvenOdd;
            PolyFillType pftClip = PolyFillType.pftEvenOdd;
            if (args.Length > 6)
            {
                switch (args[5].ToUpper())
                {
                    case "EVENODD": pftSubj = PolyFillType.pftEvenOdd; break;
                    case "NONZERO": pftSubj = PolyFillType.pftNonZero; break;
                    default: Console.WriteLine("Error: invalid cliptype - {0}", args[5]); return;
                }
                switch (args[6].ToUpper())
                {
                    case "EVENODD": pftClip = PolyFillType.pftEvenOdd; break;
                    case "NONZERO": pftClip = PolyFillType.pftNonZero; break;
                    default: Console.WriteLine("Error: invalid cliptype - {0}", args[6]); return;
                }
            }

            Paths subjs = new Paths();
            Paths clips = new Paths();
            if (!LoadFromFile(subjFilename, subjs, decimal_places))
            {
                Console.WriteLine("Error processing subject polygons file - {0} ", subjFilename);
                OutputFileFormat();
                return;
            }
            if (!LoadFromFile(clipFilename, clips, decimal_places))
            {
                Console.WriteLine("Error processing clip polygons file - {0} ", clipFilename);
                OutputFileFormat();
                return;
            }

            Console.WriteLine("wait ...");
            Clipper cp = new Clipper();
            cp.AddPaths(subjs, PolyType.ptSubject, true);
            cp.AddPaths(clips, PolyType.ptClip, true);

            Paths solution = new Paths();
            //Paths solution = new Paths();
            if (cp.Execute(ct, solution, pftSubj, pftClip))
            {
                SaveToFile("solution.txt", solution, decimal_places);

                //solution = Clipper.OffsetPolygons(solution, -4, JoinType.jtRound);

                SVGBuilder svg = new SVGBuilder();
                svg.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
                svg.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda);
                svg.AddPaths(subjs);
                svg.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
                svg.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a);
                svg.AddPaths(clips);
                svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
                svg.style.penClr = Color.FromArgb(0, 0x33, 0);
                svg.AddPaths(solution);
                svg.SaveToFile("solution.svg", svg_scale);

                Console.WriteLine("finished!");
            }
            else
            {
                Console.WriteLine("failed!");
            }
        }
Example #28
0
        private void SetTest()
        {
            if (!_testData.ContainsKey(_testNumber))
            {
                return;
            }

            // Get test of interest.
            var test = _testData[_testNumber];

            _testSubject  = test.Subjects.FirstOrDefault();
            _testClip     = test.Clips.FirstOrDefault();
            _testSolution = test.Solution;

            _newClipperSolution = new PolygonPath();

            var clipper = new Clipper.Clipper();

            clipper.AddPath(test.Subjects, PolygonKind.Subject);
            clipper.AddPath(test.Clips, PolygonKind.Clip);
            clipper.Execute(ClipOperation.Union, _newClipperSolution);

            _testBoundary = _testSolution.Any()
                ? BoundaryBuilder
                            .BuildPolygonBoundary(_testSolution.First(), PolygonKind.Subject)
                            .ToList()
                : null;

            _newClipperBoundary = _newClipperSolution.Any()
                ? BoundaryBuilder
                                  .BuildPolygonBoundary(_newClipperSolution.First(), PolygonKind.Subject)
                                  .ToList()
                : null;

            var originalClipperSolution = new List <List <IntPoint> >();
            var originalClipper         = new ClipperLib.Clipper();

            originalClipper.AddPaths(test.Subjects.ToOriginal(), PolyType.ptSubject, true);
            originalClipper.AddPaths(test.Clips.ToOriginal(), PolyType.ptClip, true);
            originalClipper.Execute(ClipType.ctUnion, originalClipperSolution);
            _originalClipperSolution = originalClipperSolution.ToNew();

            _originalClipperBoundary = _originalClipperSolution.Any()
                ? BoundaryBuilder
                                       .BuildPolygonBoundary(_originalClipperSolution.First(), PolygonKind.Subject)
                                       .ToList()
                : null;

            Program.VisualizerForm.ClipperViewControl.Subjects = new[]
            {
                new PolygonViewModel
                {
                    IsOpen      = false,
                    EdgeColor   = Color.LawnGreen,
                    VertexColor = Color.DarkGreen,
                    Items       = _testSubject?.ToVertices()
                }
            };

            Program.VisualizerForm.ClipperViewControl.Clips = new[]
            {
                new PolygonViewModel
                {
                    IsOpen      = false,
                    EdgeColor   = Color.Blue,
                    VertexColor = Color.DarkBlue,
                    Items       = _testClip?.ToVertices()
                }
            };

            _solutionType = SolutionType.Test;
            SetSolution();
            solutionComboBox.SelectedIndex = 0;
        }
Example #29
0
 private static Vector2 getCollisionPointClosest(PolygonSet p1, PolygonSet p2, Vector2 point)
 {
     Clipper clipper = new Clipper();
     PolygonSet result = new PolygonSet();
     clipper.AddPaths(p1, PolyType.ptClip, true);
     clipper.AddPaths(p2, PolyType.ptSubject, true);
     bool succeeded = clipper.Execute(ClipType.ctIntersection, result, PolyFillType.pftPositive, PolyFillType.pftPositive);
     clipper.Clear();
     return getClosestPoint(result, new Vector2(point.X,point.Y));
 }
Example #30
0
		public static void GenerateHexLinePaths(Polygons in_outline, ref Polygons result, int lineSpacing, int infillExtendIntoPerimeter_um, double rotationDegrees, int layerIndex)
		{
			int extraRotationAngle = 0;
			if (in_outline.Count > 0)
			{
				Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um);
				if (outlines.Count > 0)
				{
					int perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5);
					PointMatrix matrix = new PointMatrix(-(rotationDegrees + extraRotationAngle)); // we are rotating the part so we rotate by the negative so the lines go the way we expect

					outlines.ApplyMatrix(matrix);

					Aabb boundary = new Aabb(outlines);

					boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
					boundary.min.Y = ((boundary.min.Y / perIncrementOffset) - 2) * perIncrementOffset;
					boundary.max.X += lineSpacing;
					boundary.max.Y += perIncrementOffset;
					Polygons unclipedPatern = new Polygons();

					foreach (IntPoint startPoint in StartPositionIterator(boundary, lineSpacing, layerIndex))
					{
						Polygon attachedLine = new Polygon();
						foreach (IntPoint center in IncrementPositionIterator(startPoint, boundary, lineSpacing, layerIndex))
						{
							// what we are adding are the little plusses that define the points
							//        | top
							//        |
							//        /\ center
							//   left/  \ right
							//
							IntPoint left = center + new IntPoint(-lineSpacing / 2, -perIncrementOffset / 3);
							IntPoint right = center + new IntPoint(lineSpacing / 2, -perIncrementOffset / 3);
							IntPoint top = center + new IntPoint(0, perIncrementOffset * 2 / 3);

							switch (layerIndex % 3)
							{
								case 0: // left to right
									attachedLine.Add(left); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(right);
									unclipedPatern.Add(new Polygon() { top, center });
									break;

								case 1: // left to top
									attachedLine.Add(left); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(top);
									unclipedPatern.Add(new Polygon() { center, right });
									break;

								case 2: // top to right
									attachedLine.Add(top); attachedLine.Add(center);
									attachedLine.Add(center); attachedLine.Add(right);
									unclipedPatern.Add(new Polygon() { left, center });
									break;
							}
						}
						if (attachedLine.Count > 0)
						{
							unclipedPatern.Add(attachedLine);
						}
					}

					PolyTree ret = new PolyTree();
					Clipper clipper = new Clipper();
					clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false);
					clipper.AddPaths(outlines, PolyType.ptClip, true);
					clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd);

					Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret);
					PointMatrix inversematrix = new PointMatrix((rotationDegrees + extraRotationAngle));
					newSegments.ApplyMatrix(inversematrix);

					result.AddRange(newSegments);
				}
			}
		}
Example #31
0
		public static Polygons CreateUnion(this Polygons polygons, Polygons other)
		{
			Clipper clipper = new Clipper();
			clipper.AddPaths(polygons, PolyType.ptSubject, true);
			clipper.AddPaths(other, PolyType.ptSubject, true);

			Polygons ret = new Polygons();
			clipper.Execute(ClipType.ctUnion, ret, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
			return ret;
		}
Example #32
0
		public static Polygons ProcessEvenOdd(this Polygons polygons)
		{
			Polygons ret = new Polygons();
			Clipper clipper = new Clipper();
			clipper.AddPaths(polygons, PolyType.ptSubject, true);
			clipper.Execute(ClipType.ctUnion, ret);
			return ret;
		}
Example #33
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;
        }
Example #34
0
        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);
            }
        }
Example #35
0
        public static PolyTree ExecuteClipper(TmxMap tmxMap, TmxLayer tmxLayer, TransformPointFunc xfFunc, ProgressFunc progFunc)
        {
            // The "fullClipper" combines the clipper results from the smaller pieces
            ClipperLib.Clipper fullClipper = new ClipperLib.Clipper();

            // From the perspective of Clipper lines are polygons too
            // Closed paths == polygons
            // Open paths == lines
            var polygonGroups = from y in Enumerable.Range(0, tmxLayer.Height)
                                from x in Enumerable.Range(0, tmxLayer.Width)
                                let rawTileId = tmxLayer.GetRawTileIdAt(x, y)
                                                let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId)
                                                             where tileId != 0
                                                             let tile = tmxMap.Tiles[tileId]
                                                                        from polygon in tile.ObjectGroup.Objects
                                                                        where (polygon as TmxHasPoints) != null
                                                                        let groupX = x / LayerClipper.GroupBySize
                                                                                     let groupY = y / LayerClipper.GroupBySize
                                                                                                  group new
            {
                PositionOnMap         = tmxMap.GetMapPositionAt(x, y, tile),
                HasPointsInterface    = polygon as TmxHasPoints,
                TmxObjectInterface    = polygon,
                IsFlippedDiagnoally   = TmxMath.IsTileFlippedDiagonally(rawTileId),
                IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId),
                IsFlippedVertically   = TmxMath.IsTileFlippedVertically(rawTileId),
                TileCenter            = new PointF(tile.TileSize.Width * 0.5f, tile.TileSize.Height * 0.5f),
            }
            by Tuple.Create(groupX, groupY);

            int groupIndex = 0;
            int groupCount = polygonGroups.Count();

            foreach (var polyGroup in polygonGroups)
            {
                if (groupIndex % 5 == 0)
                {
                    progFunc(String.Format("Clipping '{0}' polygons: {1}%", tmxLayer.UniqueName, (groupIndex / (float)groupCount) * 100));
                }
                groupIndex++;

                // The "groupClipper" clips the polygons in a smaller part of the world
                ClipperLib.Clipper groupClipper = new ClipperLib.Clipper();

                // Add all our polygons to the Clipper library so it can reduce all the polygons to a (hopefully small) number of paths
                foreach (var poly in polyGroup)
                {
                    // Create a clipper library polygon out of each and add it to our collection
                    ClipperPolygon clipperPolygon = new ClipperPolygon();

                    // Our points may be transformed due to tile flipping/rotation
                    // Before we transform then we put all the points into local space relative to the tile
                    SizeF    offset            = new SizeF(poly.TmxObjectInterface.Position);
                    PointF[] transformedPoints = poly.HasPointsInterface.Points.Select(pt => PointF.Add(pt, offset)).ToArray();

                    // Now transform the points relative to the tile
                    TmxMath.TransformPoints(transformedPoints, poly.TileCenter, poly.IsFlippedDiagnoally, poly.IsFlippedHorizontally, poly.IsFlippedVertically);

                    foreach (var pt in transformedPoints)
                    {
                        float x = poly.PositionOnMap.X + pt.X;
                        float y = poly.PositionOnMap.Y + pt.Y;

                        ClipperLib.IntPoint point = xfFunc(x, y);
                        clipperPolygon.Add(point);
                    }

                    // Because of Unity's cooridnate system, the winding order of the polygons must be reversed
                    clipperPolygon.Reverse();

                    // Add the "subject"
                    groupClipper.AddPath(clipperPolygon, ClipperLib.PolyType.ptSubject, poly.HasPointsInterface.ArePointsClosed());
                }

                // Get a solution for this group
                ClipperLib.PolyTree solution = new ClipperLib.PolyTree();
                groupClipper.Execute(ClipperLib.ClipType.ctUnion, solution);

                // Combine the solutions into the full clipper
                fullClipper.AddPaths(Clipper.ClosedPathsFromPolyTree(solution), PolyType.ptSubject, true);
                fullClipper.AddPaths(Clipper.OpenPathsFromPolyTree(solution), PolyType.ptSubject, false);
            }
            progFunc(String.Format("Clipping '{0}' polygons: 100%", tmxLayer.UniqueName));

            ClipperLib.PolyTree fullSolution = new ClipperLib.PolyTree();
            fullClipper.Execute(ClipperLib.ClipType.ctUnion, fullSolution);

            return(fullSolution);
        }
Example #36
0
        /// <summary>
        ///     Joins all the polygones.
        ///     ClipType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
        ///     PolyFillType: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/PolyFillType.htm
        /// </summary>
        /// <param name="sList">The s list.</param>
        /// <param name="cType">Type of the c.</param>
        /// <param name="pType">Type of the p.</param>
        /// <param name="pFType1">The p f type1.</param>
        /// <param name="pFType2">The p f type2.</param>
        /// <returns></returns>
        public static List<Polygon> ELJoinPolygons(this List<Polygon> sList, ClipType cType,
            PolyType pType = PolyType.ptClip, PolyFillType pFType1 = PolyFillType.pftNonZero,
            PolyFillType pFType2 = PolyFillType.pftNonZero)
        {
            var p = ELClipPolygons(sList);
            var tList = new List<List<IntPoint>>();

            var c = new Clipper();
            c.AddPaths(p, pType, true);
            c.Execute(cType, tList, pFType1, pFType2);

            return ToPolygons(tList);
        }
Example #37
0
		public static Polygons CreateLineDifference(this Polygons linePolygons, Polygons removePolygons)
		{
			Clipper clipper = new Clipper();

			clipper.AddPaths(linePolygons, PolyType.ptSubject, false);
			clipper.AddPaths(removePolygons, PolyType.ptClip, true);

			PolyTree clippedLines = new PolyTree();

			clipper.Execute(ClipType.ctDifference, clippedLines);

			return Clipper.OpenPathsFromPolyTree(clippedLines);
		}
		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.AddPaths(lineLoops, PolyType.ptSubject, true);
			clipper.AddPath(boundingPoly, PolyType.ptClip, true);

			PolyTree polyTreeForPlate = new PolyTree();
			clipper.Execute(ClipType.ctIntersection, polyTreeForPlate);

			return polyTreeForPlate;
		}
        /// <summary>
        /// Performs the Boolean Operations from the Clipper Library
        /// </summary>
        /// <param name="clipType"></param>
        /// <param name="subject"></param>
        /// <param name="clip"></param>
        /// <param name="simplifyPriorToBooleanOperation"></param>
        /// <param name="scale"></param>
        /// <param name="fillMethod"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static List <Polygon> BooleanViaClipper(PolyFillType fillMethod, ClipType clipType, IEnumerable <Polygon> subject,
                                                        IEnumerable <Polygon> clip = null, bool subjectIsClosed = true, bool clipIsClosed = true)
        {
            //Remove any polygons that are only a line.
            //subject = subject.Where(p => p.Count > 2);
            //clip = clip?.Where(p => p.Count > 2);
            var simplifyPriorToBooleanOperation = true;

            if (simplifyPriorToBooleanOperation)
            {
                //subject = subject.Select(p=>SimplifyFuzzy(p));
                subject = subject.Select(p => Simplify(p, 0.0000003));
            }
            if (simplifyPriorToBooleanOperation)
            {
                //If not null
                //clip = clip?.Select(p => SimplifyFuzzy(p));
                clip = clip?.Select(p => Simplify(p, 0.0000003));
            }
            if (!subject.Any())
            {
                if (clip == null || !clip.Any())
                {
                    return(new List <Polygon>());
                }
                //Use the clip as the subject if this is a union operation and the clip is not null.
                if (clipType == ClipType.ctUnion)
                {
                    subject = clip;
                    clip    = null;
                }
            }
            var subjectAll = subject.SelectMany(p => p.AllPolygons).ToList();

            var clipperSolution = new List <List <IntPoint> >();
            //Convert Points (TVGL) to IntPoints (Clipper)
            var clipperSubject =
                subjectAll.Select(loop => loop.Vertices.Select(point => new IntPoint(point.X * scale, point.Y * scale)).ToList()).ToList();

            //Setup Clipper
            var clipper = new ClipperLib.Clipper()
            {
                StrictlySimple = true
            };

            clipper.AddPaths(clipperSubject, PolyType.ptSubject, subjectIsClosed);

            if (clip != null)
            {
                var clipAll = clip.SelectMany(p => p.AllPolygons).ToList();

                var clipperClip =
                    clipAll.Select(loop => loop.Vertices.Select(point => new IntPoint(point.X * scale, point.Y * scale)).ToList()).ToList();
                clipper.AddPaths(clipperClip, PolyType.ptClip, clipIsClosed);
            }

            //Begin an evaluation
            var result = clipper.Execute(clipType, clipperSolution, fillMethod, fillMethod);

            if (!result)
            {
                throw new Exception("Clipper Union Failed");
            }

            //Convert back to points and return solution
            var solution = clipperSolution.Select(clipperPath => new Polygon(clipperPath.Select(point => new Vector2(point.X / scale, point.Y / scale))));

            return(solution.CreateShallowPolygonTrees(true));
        }