/// <summary> /// Returns the other triangle than the given triangle on the graph /// Returns null if no such triangle could be found. /// </summary> /// <param name="t"></param> /// <returns></returns> public Triangle GetOtherTriangle(Triangle t) { var otherVertexOfTriangle = t.GetVertices().Single(o => o != v1 && o != v2); var triangleMembers = GetTriangleMembers(); //if (triangleMembers.Count() > 2) //throw new InvalidOperationException("Edge with more than two triangles?"); //TODO: Something goes wrong here! This should never be larger than 1!!! var otherTriangleMember = triangleMembers.FirstOrDefault(o => o != otherVertexOfTriangle); if (otherTriangleMember == null) return null; var edges = new List<Edge>() { this }; otherTriangleMember.Edges.ForEach(o => { if ((o.v1 == v1 || o.v1 == v2 || o.v2 == v1 || o.v2 == v2)) edges.Add(o); }); if (edges.Count != 3) throw new InvalidOperationException("Triangle with no 3 edges"); var triangle = new Triangle() { Edges = edges}; return triangle; }
/// <summary> /// Recursively retrieves all conflicting triangles with P based on their circumcircle /// This method should be O(S) where S is the number of conflicting triangles, which is constant for a convex polygon /// However due to a bug this seems to be untrue. /// </summary> /// <param name="P"></param> /// <param name="currentTriangle"></param> /// <param name="SearchNr"></param> /// <param name="conflicting"></param> /// <returns></returns> private List<Triangle> GetRecursiveConflicitingTriangles(Vertex P, Triangle currentTriangle, int SearchNr, Edge conflicting) { var result = new List<Triangle>(); if(currentTriangle == null) return result; currentTriangle.conflictingEdge = conflicting; var center = currentTriangle.CreateTriangle().GetCircumCentre(); if (center.Distance(P.Point) <= center.Distance(currentTriangle.Edges[0].v1.Point)) { //If the circumcircle contains P, add the triangle to the list result.Add(currentTriangle); //And continue over all triangles adjecent to the current triangles foreach (var edge in currentTriangle.Edges) { //If the edge was not visited yet, continue if (!edge.VisitedBy.ContainsKey(SearchNr) || !edge.VisitedBy[SearchNr]) { edge.VisitedBy[SearchNr] = true; result.AddRange(GetRecursiveConflicitingTriangles(P, edge.GetOtherTriangle(currentTriangle), SearchNr, edge)); } } } return result; }
/// <summary> /// Retriangulate the given triangle with P /// Basically removes the conflicting edge from the graph and introduces a new one from the vertex that was not on the removed edge and P /// </summary> /// <param name="triangle"></param> /// <param name="P"></param> private void Retriangulate(Triangle triangle, Vertex P) { var otherVertex = triangle.GetVertices().Single(o => o != triangle.conflictingEdge.v1 && o != triangle.conflictingEdge.v2); GM.DestroyEdge(triangle.conflictingEdge); GM.CreateOrGet(otherVertex, P); }
/// <summary> /// Creates a new triangle on the given vertices /// Creades the edges if needed /// Updates references on existing edges /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="v3"></param> /// <returns></returns> public Triangle CreateTriangleAndEdges(Vertex v1, Vertex v2, Vertex v3) { var triangle = new Triangle(); var edge1 = CreateOrGet(v1, v2); var edge2 = CreateOrGet(v2, v3); var edge3 = CreateOrGet(v3, v1); triangle.Edges.Add(edge1); triangle.Edges.Add(edge2); triangle.Edges.Add(edge3); return triangle; }