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]) }");
        }