/// <summary> /// Flips the given triangle edge in the triangulation. /// Flipping for Delaunay means changing the edge for the adjacent two triangles to the other possibility. /// </summary> /// <param name="T"></param> /// <param name="a_Edge"></param> private static void Flip(Triangulation T, TriangleEdge a_Edge) { var a_Triangle = a_Edge.T; var a_Twin = a_Edge.Twin.T; if (a_Triangle == null || a_Twin == null) { throw new GeomException("Cannot flip edge if neighbouring triangles don't exist"); } // retrieve other adjacent edges to edge vertices // e3 . e1 // / | \ // . | . // \ | / // e2 . e0 var e0 = a_Triangle.OtherEdge(a_Edge, a_Edge.Point1); var e1 = a_Triangle.OtherEdge(a_Edge, a_Edge.Point2); var e2 = a_Twin.OtherEdge(a_Edge.Twin, a_Edge.Point1); var e3 = a_Twin.OtherEdge(a_Edge.Twin, a_Edge.Point2); // create new triangle edges var euv = new TriangleEdge(e0.Point1, e2.Point2, null, null); var evu = new TriangleEdge(e2.Point2, e0.Point1, euv, null); euv.Twin = evu; // Remove old triangles T.RemoveTriangle(a_Triangle); T.RemoveTriangle(a_Twin); // add new triangles T.AddTriangle(new Triangle(e0, e2, evu)); T.AddTriangle(new Triangle(e3, e1, euv)); }
public void InValidTriangulationTest() { var m_delaunay = new Triangulation(); var t1 = new Triangle(m_topVertex, m_rightVertex, m_botVertex); var t2 = new Triangle(m_topVertex, m_botVertex, m_leftVertex); t1.E2.Twin = t2.E0; t2.E0.Twin = t1.E2; m_delaunay.AddTriangle(t1); m_delaunay.AddTriangle(t2); Assert.IsFalse(Delaunay.IsValid(m_delaunay)); }
public void AddTriangleTest() { var tr = new Triangle(v1, v2, v4); var T2 = new Triangulation(); T2.AddTriangle(tr); Assert.AreEqual(1, T2.Triangles.Count); }
public TriangulationTest() { v1 = new Vector2(0, 0); v2 = new Vector2(1, 1); v3 = new Vector2(2, 0); v4 = new Vector2(1, -1); e1 = new TriangleEdge(v1, v2); e2 = new TriangleEdge(v2, v3); e3 = new TriangleEdge(v3, v1); t1 = new Triangle(e1, e2, e3); e4 = new TriangleEdge(v1, v3); e5 = new TriangleEdge(v3, v4); e6 = new TriangleEdge(v4, v1); t2 = new Triangle(e4, e5, e6); T = new Triangulation(); T.AddTriangle(t1); T.AddTriangle(t2); }
/// <summary> /// Triangulates the polygon recursively. /// Finds the leftmost point and creates a triangle with that or splits polygon in two. /// </summary> /// <param name="vertices"></param> /// <returns></returns> private static Triangulation TriangulateRecursive(List <Vector2> vertices) { if (vertices.Count == 3) { return(new Triangulation(vertices)); } var triangulation = new Triangulation(); //Find leftmost vertex var leftVertex = LeftMost(vertices); var index = vertices.IndexOf(leftVertex); var prevVertex = vertices[MathUtil.PositiveMod(index - 1, vertices.Count)]; var nextVertex = vertices[MathUtil.PositiveMod(index + 1, vertices.Count)]; //Create triangle with diagonal Debug.Assert(leftVertex != prevVertex && leftVertex != nextVertex && prevVertex != nextVertex); var triangle = new Triangle(prevVertex, leftVertex, nextVertex); //check for other vertices inside the candidate triangle var baseline = new Line(prevVertex, nextVertex); float distance = -1f; int diagonalIndex = -1; for (int i = 0; i < vertices.Count; i++) { var v = vertices[i]; if (v != leftVertex && v != prevVertex && v != nextVertex && triangle.Contains(v)) { if (baseline.DistanceToPoint(v) > distance) { distance = baseline.DistanceToPoint(v); diagonalIndex = i; } } } //Do Recursive call if (diagonalIndex == -1) //didn't change { if (!triangle.IsClockwise()) { // shouldnt happen but in case it does // reverse triangle triangle = new Triangle(triangle.P0, triangle.P2, triangle.P1); } triangulation.AddTriangle(triangle); vertices.Remove(leftVertex); triangulation.AddTriangulation(TriangulateRecursive(vertices)); } else { var minIndex = Mathf.Min(index, diagonalIndex); var maxIndex = Mathf.Max(index, diagonalIndex); var poly1List = vertices.Skip(minIndex).Take(maxIndex - minIndex + 1).ToList(); var poly2List = vertices.Skip(maxIndex).Concat(vertices.Take(minIndex + 1)).ToList(); triangulation.AddTriangulation(TriangulateRecursive(poly1List)); triangulation.AddTriangulation(TriangulateRecursive(poly2List)); } return(triangulation); }