public void MissingEdgeInDictionary() { var builder = PlanePolygonBuilder.CreatePolygonBuilder(); builder.AddEdge(new Vector3(1.88157800f, 0.28075720f, 0), new Vector3(1.61366200f, -0.06876162f, 0)); builder.AddEdge(new Vector3(2.00597400f, 0.44304200f, 0), new Vector3(1.88157800f, 0.28075720f, 0)); builder.AddEdge(new Vector3(-0.36652940f, 1.35938300f, 0), new Vector3(0.46412470f, 2.44304200f, 0)); builder.AddEdge(new Vector3(-0.87735590f, 0.69296650f, 0), new Vector3(-0.36652910f, 1.35938300f, 0)); builder.AddEdge(new Vector3(-0.49218100f, 0.19333940f, 0), new Vector3(-0.87735590f, 0.69296650f, 0)); builder.AddEdge(new Vector3(0.00744601f, -0.45474870f, 0), new Vector3(-0.49218100f, 0.19333940f, 0)); builder.AddEdge(new Vector3(1.14250100f, -0.18199130f, 0), new Vector3(0.21764320f, -0.40423650f, 0)); builder.AddEdge(new Vector3(1.61366200f, -0.06876162f, 0), new Vector3(1.14250100f, -0.18199130f, 0)); builder.AddEdge(new Vector3(0.21764320f, -0.40423650f, 0), new Vector3(0.00744601f, -0.45474870f, 0)); builder.AddEdge(new Vector3(0.46412470f, 2.44304200f, 0), new Vector3(1.09203400f, 1.62855300f, 0)); builder.AddEdge(new Vector3(1.09203400f, 1.62855300f, 0), new Vector3(2.00597400f, 0.44304200f, 0)); builder.AddEdge(new Vector3(1.14250100f, -0.18199130f, 0), new Vector3(1.06736400f, 1.22428300f, 0)); builder.AddEdge(new Vector3(0.50145080f, 1.27333500f, 0), new Vector3(-0.01388439f, 1.31800400f, 0)); builder.AddEdge(new Vector3(1.06736400f, 1.22428300f, 0), new Vector3(0.50145070f, 1.27333500f, 0)); builder.AddEdge(new Vector3(0.01580662f, 0.76231190f, 0), new Vector3(0.06125379f, -0.08827398f, 0)); builder.AddEdge(new Vector3(-0.01388440f, 1.31800400f, 0), new Vector3(0.01580662f, 0.76231190f, 0)); builder.AddEdge(new Vector3(0.17275270f, -0.09793866f, 0), new Vector3(1.14250100f, -0.18199130f, 0)); builder.AddEdge(new Vector3(0.06125382f, -0.08827414f, 0), new Vector3(0.17275270f, -0.09793866f, 0)); var polygon = builder.BuildPolygon(); Assert.IsNotNull(polygon); }
public void EdgesWithTwoTouchingPolygons() { var builder = PlanePolygonBuilder.CreatePolygonBuilder(); builder.AddEdge(new Vector3(1.363289f, 0.325342f, 0), new Vector3(0.532633f, -0.758319f, 0)); builder.AddEdge(new Vector3(1.874113f, 0.991756f, 0), new Vector3(1.363289f, 0.325342f, 0)); builder.AddEdge(new Vector3(-0.884818f, 1.403969f, 0), new Vector3(-0.616898f, 1.753494f, 0)); builder.AddEdge(new Vector3(-1.009216f, 1.241681f, 0), new Vector3(-0.884818f, 1.403969f, 0)); builder.AddEdge(new Vector3(-0.256794f, 0.265680f, 0), new Vector3(-1.009216f, 1.241681f, 0)); builder.AddEdge(new Vector3(0.532633f, -0.758319f, 0), new Vector3(-0.256793f, 0.265680f, 0)); builder.AddEdge(new Vector3(0.989307f, 2.139478f, 0), new Vector3(1.874113f, 0.991756f, 0)); builder.AddEdge(new Vector3(-0.616898f, 1.753494f, 0), new Vector3(-0.145745f, 1.866717f, 0)); builder.AddEdge(new Vector3(-0.145745f, 1.866717f, 0), new Vector3(0.779111f, 2.088966f, 0)); builder.AddEdge(new Vector3(0.779111f, 2.088966f, 0), new Vector3(0.989307f, 2.139478f, 0)); builder.AddEdge(new Vector3(0.951598f, 1.471772f, 0), new Vector3(0.935504f, 1.772997f, 0)); builder.AddEdge(new Vector3(1.010642f, 0.366718f, 0), new Vector3(0.951598f, 1.471772f, 0)); builder.AddEdge(new Vector3(0.935504f, 1.772997f, 0), new Vector3(-0.145745f, 1.866717f, 0)); builder.AddEdge(new Vector3(-0.094393f, 0.905628f, 0), new Vector3(-0.070607f, 0.460440f, 0)); builder.AddEdge(new Vector3(-0.145745f, 1.866717f, 0), new Vector3(-0.094393f, 0.905628f, 0)); builder.AddEdge(new Vector3(0.449942f, 0.415320f, 0), new Vector3(1.010642f, 0.366718f, 0)); builder.AddEdge(new Vector3(-0.070607f, 0.460440f, 0), new Vector3(0.449942f, 0.415320f, 0)); var polygon = builder.BuildPolygon().Polygon; Assert.AreEqual(1, polygon.SubPolygonIds.Count()); var triangulator = new PolygonTriangulator(polygon); var splits = triangulator.GetSplits(); Assert.IsNotNull(splits); var triangles = triangulator.BuildTriangles(); Assert.IsNotNull(triangles); }
public void PolygonizeTripleOutsideToInsideFinish() { var clockwise = new[] { new Vertex(1, 0), new Vertex(0, 1), new Vertex(2, 2), new Vertex(1, 2), new Vertex(0, 3), new Vertex(2, 4), new Vertex(1, 4), new Vertex(0, 5), new Vertex(1, 6), new Vertex(4, 6), new Vertex(5, 5), new Vertex(4, 4.5f), new Vertex(3, 3.5f), new Vertex(4, 2.5f), new Vertex(3, 1.5f), new Vertex(4, 0.5f), new Vertex(5.5f, 1), new Vertex(4.5f, 0), }; var planeMeshBuilder = new PlanePolygonBuilder(new Plane(new Vector3(0, 0, -1), 0)); var last = clockwise.Last(); foreach (var dot in clockwise) { planeMeshBuilder.AddEdge(new Vector3(last.X, last.Y, 0), new Vector3(dot.X, dot.Y, 0)); last = dot; } planeMeshBuilder.Build(); }
public void BuildPolygonFromEdges() { var clockwise = new[] { new Vertex(1, 1), new Vertex(2.5f, 2), new Vertex(2, 2), new Vertex(1, 3), new Vertex(2, 4), new Vertex(4, 4), new Vertex(1.5f, 3), new Vertex(2.5f, 3), new Vertex(4, 3.5f), // new Vertex(2.25f, 2.5f), new Vertex(3, 2.5f), new Vertex(4, 1.5f), new Vertex(3.5f, 1), new Vertex(2.5f, 1), }; var builder = PlanePolygonBuilder.CreatePolygonBuilder(); var last = clockwise.Last(); foreach (var vertex in clockwise) { builder.AddEdge(new Vector3(last.X, last.Y, 0), new Vector3(vertex.X, vertex.Y, 0)); last = vertex; } var result = builder.BuildPolygon(); Assert.AreEqual("5 0 6 3 1 4 12 2 7 11 8 10 9", string.Join(" ", result.Polygon.SubPolygonVertices(0))); }
/// <summary> /// The infamous form number one /// </summary> /// <returns>the polygon</returns> public static Polygon Form1() { var clockwise = new[] { new Vertex(1, 1), new Vertex(2.5f, 2), new Vertex(2, 2), new Vertex(1, 3), new Vertex(2, 4), new Vertex(4, 4), new Vertex(1.5f, 3), new Vertex(2.7f, 3), new Vertex(4, 3.5f), new Vertex(3, 2.5f), new Vertex(4, 1.5f), new Vertex(3.5f, 1), new Vertex(2.3f, 1), }; var polygonBuilder = PlanePolygonBuilder.CreatePolygonBuilder(); var last = clockwise.Last(); foreach (var vertex in clockwise) { polygonBuilder.AddEdge(new Vector3(last.X, last.Y, 0), new Vector3(vertex.X, vertex.Y, 0)); last = vertex; } return(polygonBuilder.BuildPolygon().Polygon); }
public void PolygonizeForm1() { var clockwise = new[] { new Vertex(1, 1), new Vertex(2.5f, 2), new Vertex(2, 2), new Vertex(1, 3), new Vertex(2, 4), new Vertex(4, 4), new Vertex(1.5f, 3), new Vertex(2.5f, 3), new Vertex(4, 3.5f), // new Vertex(2.25f, 2.5f), new Vertex(3, 2.5f), new Vertex(4, 1.5f), new Vertex(3.5f, 1), new Vertex(2.5f, 1), }; var counter = new[] { new Vertex(3, 3), new Vertex(2, 2.5f), new Vertex(3, 2), new Vertex(2.5f, 2.5f), }; var planeMeshBuilder = new PlanePolygonBuilder(new Plane(new Vector3(0, 0, -1), 0)); var last = clockwise.Last(); foreach (var vertex in clockwise) { planeMeshBuilder.AddEdge(new Vector3(last.X, last.Y, 0), new Vector3(vertex.X, vertex.Y, 0)); last = vertex; } last = counter.Last(); foreach (var dot in counter) { planeMeshBuilder.AddEdge(new Vector3(last.X, last.Y, 0), new Vector3(dot.X, dot.Y, 0)); last = dot; } var result = planeMeshBuilder.Build(); for (int i = 0; i < result.Triangles.Length; i += 3) { this.TestContext.WriteLine($"{result.Triangles[i + 0]} {result.Triangles[i + 1]} {result.Triangles[i + 2]}"); } Assert.AreEqual(3 * 17, result.Triangles.Length); }
public void BadSelfCrossing() { var builder = new PlanePolygonBuilder(new Plane()); builder.AddEdge(new Vector3(1, 0, 0), new Vector3(1, 3, 0)); builder.AddEdge(new Vector3(1, 3, 0), new Vector3(3, 1, 0)); builder.AddEdge(new Vector3(3, 1, 0), new Vector3(3, 3, 0)); builder.AddEdge(new Vector3(3, 3, 0), new Vector3(1, 0, 0)); builder.Build(); Assert.Fail("May not reach this point"); }
public static Polygon UnityError6() { ////var vertices = new[] ////{ //// new Vertex(0.97032920f, 0.81851240f), //// new Vertex(0.97592230f, 0.92531130f), //// new Vertex(1.01729100f, 1.71523700f), //// new Vertex(1.02747200f, 1.90963600f), //// new Vertex(1.07189700f, 2.75792400f), //// new Vertex(1.07534400f, 2.82374700f), //// new Vertex(1.26485600f, 1.71643700f), //// new Vertex(1.38595200f, 0.79852870f), //// new Vertex(2.90666200f, 2.73569500f), //// new Vertex(2.97032900f, 0.72234950f), //// new Vertex(2.97468800f, 0.80557190f), //// new Vertex(3.02283700f, 1.72496800f), //// new Vertex(3.07318800f, 2.68641600f), //// new Vertex(3.07534400f, 2.72758500f), ////}; ////var polygon = Polygon.Build(vertices) //// .AddVertices(6, 11, 10, 9, 7, 0, 1, 2) //// .ClosePartialPolygon() //// .AddVertices(12, 11, 3, 4, 5, 8, 13) //// .ClosePartialPolygon() //// .Close(11); var builder = PlanePolygonBuilder.CreatePolygonBuilder(); builder.AddEdge(new Vector3(1.38595200f, 0.79852870f, 0), new Vector3(0.97032920f, 0.81851240f, 0)); builder.AddEdge(new Vector3(2.97032900f, 0.72234950f, 0), new Vector3(1.38595200f, 0.79852870f, 0)); builder.AddEdge(new Vector3(3.02283700f, 1.72496800f, 0), new Vector3(2.97468800f, 0.80557190f, 0)); builder.AddEdge(new Vector3(3.07318800f, 2.68641600f, 0), new Vector3(3.02283700f, 1.72496800f, 0)); builder.AddEdge(new Vector3(3.07534400f, 2.72758500f, 0), new Vector3(3.07318800f, 2.68641600f, 0)); builder.AddEdge(new Vector3(2.97468800f, 0.80557190f, 0), new Vector3(2.97032900f, 0.72234950f, 0)); builder.AddEdge(new Vector3(2.90666200f, 2.73569500f, 0), new Vector3(3.07534400f, 2.72758500f, 0)); builder.AddEdge(new Vector3(1.07534400f, 2.82374700f, 0), new Vector3(2.90666200f, 2.73569500f, 0)); builder.AddEdge(new Vector3(1.02747200f, 1.90963600f, 0), new Vector3(1.07189700f, 2.75792400f, 0)); builder.AddEdge(new Vector3(0.97592230f, 0.92531120f, 0), new Vector3(1.01729100f, 1.71523700f, 0)); builder.AddEdge(new Vector3(0.97032920f, 0.81851240f, 0), new Vector3(0.97592230f, 0.92531130f, 0)); builder.AddEdge(new Vector3(1.07189700f, 2.75792400f, 0), new Vector3(1.07534400f, 2.82374700f, 0)); builder.AddEdge(new Vector3(3.02283700f, 1.72496800f, 0), new Vector3(1.02747200f, 1.90963600f, 0)); builder.AddEdge(new Vector3(1.26485600f, 1.71643700f, 0), new Vector3(3.02283700f, 1.72496800f, 0)); builder.AddEdge(new Vector3(1.01729100f, 1.71523700f, 0), new Vector3(1.26485600f, 1.71643700f, 0)); var result = builder.BuildPolygon(); return(result.Polygon); }
public void ClosePolygonByClustering() { // the unclustered vertices are marked by a comma var vertices = new[] { new Vertex(1.01627400f, 1.00386400f), new Vertex(1.02017700f, 2.99803400f), new Vertex(1.02018900f, 3.00386400f), new Vertex(1.26823400f, 2.00337700f), new Vertex(1.27069300f, 2.00090800f), new Vertex(2.01677300f, 1.25191600f), new Vertex(2.01844100f, 1.25357900f), new Vertex(2.01913800f, 2.75134700f), new Vertex(2.01970900f, 2.75191600f), new Vertex(2.23454600f, 3.00149800f), // 9 new Vertex(2.23458400f, 3.00149800f), // 10 new Vertex(2.30700800f, 2.82314500f), // 11 new Vertex(2.30704000f, 2.82315300f), // 12 new Vertex(2.55383800f, 2.21570200f), new Vertex(2.67784600f, 1.91040700f), // 14 new Vertex(2.67786500f, 1.91042500f), // 15 new Vertex(2.96702000f, 1.19871200f), // 16 new Vertex(2.96705400f, 1.19857300f), // 17 new Vertex(3.01614100f, 0.99996810f), new Vertex(3.01629300f, 0.99996780f), new Vertex(3.01629300f, 1.00011800f), new Vertex(3.01644400f, 1.07706200f), }; var lineDetector = PlanePolygonBuilder.CreatePolygonLineDetector(); lineDetector.JoinEdgesToPolygones(new[] { 18, 0, 19, 18, 2, 10, 1, 2, 0, 1, 14, 17, 16, 21, 12, 13, 9, 11, 21, 20, 20, 19, 6, 15, 5, 6, 13, 8, 7, 3, 8, 7, 4, 5, 3, 4 }); Assert.AreNotEqual(0, lineDetector.UnclosedPolygons.Count()); lineDetector.TryClusteringUnclosedEnds(vertices, 0.001f); Assert.AreEqual(1, lineDetector.ClosedPolygons.Count()); Assert.AreEqual(0, lineDetector.UnclosedPolygons.Count()); Assert.AreEqual(1, lineDetector.ClosedPolygons.First().Count(x => x == 9 || x == 10)); Assert.AreEqual(1, lineDetector.ClosedPolygons.First().Count(x => x == 11 || x == 12)); Assert.AreEqual(1, lineDetector.ClosedPolygons.First().Count(x => x == 14 || x == 15)); Assert.AreEqual(1, lineDetector.ClosedPolygons.First().Count(x => x == 16 || x == 17)); }
public void PolygonJoinSegmentsTest() { var edges = new List <int> { // first - close 00 + 1, 00 + 2, 00 + 3, 00 + 4, 00 + 2, 00 + 3, // join to 1 2 3 4 with [2 3] 00 + 4, 00 + 1, // close with [41] // same 10 + 1, 10 + 2, 10 + 3, 10 + 4, 10 + 2, 10 + 3, // join to 1 2 3 4 10 + 1, 10 + 4, // close with [14] // second 20 + 1, 20 + 2, 20 + 3, 20 + 4, 20 + 1, 20 + 3, // join to 2 1 3 4 with [1 3] 20 + 2, 20 + 4, // close // same 30 + 1, 30 + 2, 30 + 3, 30 + 4, 30 + 3, 30 + 1, // join to 2 1 3 4 with [3 1] 30 + 2, 30 + 4, // close // third 40 + 1, 40 + 2, 40 + 3, 40 + 4, 40 + 1, 40 + 4, // join to 3 4 1 2 with [1 4] 40 + 2, 40 + 3, // close // same 50 + 1, 50 + 2, 50 + 3, 50 + 4, 50 + 1, 50 + 4, // join to 3 4 1 2 with [4 1] 50 + 2, 50 + 3, // close // fourth 60 + 1, 60 + 2, 60 + 3, 60 + 4, 60 + 2, 60 + 4, // join to 1 2 4 3 with [2 4] 60 + 1, 60 + 3, // close // same 70 + 1, 70 + 2, 70 + 3, 70 + 4, 70 + 2, 70 + 4, // join to 1 2 4 3 with [4 2] 70 + 1, 70 + 3, // close }; var builder = PlanePolygonBuilder.CreatePolygonLineDetector(); builder.JoinEdgesToPolygones(edges); var result = builder.ClosedPolygons.ToArray(); Assert.AreEqual(0, builder.UnclosedPolygons.Count()); Assert.AreEqual(8, result.Length); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 3, 4 }, result[0].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[0]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 3, 4 }, result[1].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[1]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 4, 3 }, result[2].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[2]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 3, 4, 2 }, result[3].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[3]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 3, 4 }, result[4].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[4]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 3, 4 }, result[5].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[5]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 4, 3 }, result[6].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[6]) }"); Assert.IsTrue(ComparePolygon(new[] { 1, 2, 4, 3 }, result[7].Select(x => x % 10)), $"Unexpected { String.Join(" ", result[7]) }"); }