public static List <Vector2> Combine(PolygonTree tree) { List <Vector2> exVertices = new List <Vector2>(tree.exterior.vertices); if (!ForceEarCut.AreVerticesClockwise(exVertices, 0, exVertices.Count)) { exVertices.Reverse(); } if (tree.interiors == null || tree.interiors.Count == 0) { return(exVertices); } List <List <Vector2> > inPolygons = new List <List <Vector2> >(tree.interiors.Count); foreach (Polygon inPoly in tree.interiors) { List <Vector2> verts = new List <Vector2>(inPoly.vertices); if (!ForceEarCut.AreVerticesClockwise(verts, 0, verts.Count)) { verts.Reverse(); } inPolygons.Add(verts); } return(Combine(exVertices, inPolygons)); }
public void NewClipperFileBasedTest() { var testData = LoadTestHelper.LoadFromFile("TestData/tests.txt"); foreach (var test in testData.Values) { var clipper = new Clipper.Clipper(); clipper.AddPath(test.Subjects, PolygonKind.Subject); clipper.AddPath(test.Clips, PolygonKind.Clip); var solution = new PolygonTree(); Assert.IsTrue(clipper.Execute(test.ClipOperation, solution, false, test.FillType)); var path = new PolygonPath(solution.AllPolygons.Select(n => n.Polygon).ToList()); // 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, path.Count, $"{test.TestNumber}: {test.Caption}"); // Match points, THIS IS DESTRUCTIVE TO BOTH THE TEST DATA AND RESULT DATA. Assert.IsTrue(AreSame(test, path)); // 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, path.Count, $"{test.TestNumber}: {test.Caption}"); } }
public static void ShapeCopy(ref PolygonTree src, ref PolygonTree dst) { dst.exterior.vertices = new List <Vector2>(src.exterior.vertices); if (dst.interiors.Count > 0) { dst.interiors.Clear(); } foreach (Polygon inter in src.interiors) { Polygon interior = new Polygon(); interior.vertices = new List <Vector2>(inter.vertices); dst.interiors.Add(interior); } }
/// <summary> /// Определить, какие отверстия относятся к каким полигонам /// При этом сами полигоны могут быть вложены друг в друга /// </summary> /// <param name="polygons"></param> /// <param name="holes"></param> /// <returns></returns> public static List <PolygonWithNested> ResolveHoles (List <List <Point3d> > polygons, List <List <Point3d> > holes) { //Сначала определить вложенность полигонов PolygonTree tree = new PolygonTree(); int i = 0; foreach (List <Point3d> p in polygons) { tree.InsertOuterPolygon(p); i++; } //Для каждого отверстия определить полигон, в который оно вложено, находящийся на наинизшем уровне вложенности foreach (List <Point3d> hole in holes) { tree.InsertHole(hole); } return(tree.GetPolygonsWithHoles()); }