public static FindCircumcenter ( System.Point torg, System.Point tdest, System.Point tapex, double &xi, double &eta ) : System.Point | ||
torg | System.Point | Triangle point. |
tdest | System.Point | Triangle point. |
tapex | System.Point | Triangle point. |
xi | double | Relative coordinate of new location. |
eta | double | Relative coordinate of new location. |
return | System.Point |
/// <summary> /// Inserts a vertex at the circumcenter of a triangle. Deletes /// the newly inserted vertex if it encroaches upon a segment. /// </summary> /// <param name="badtri"></param> private void SplitTriangle(BadTriangle badtri) { Otri badotri = default(Otri); Vertex borg, bdest, bapex; Point newloc; // Location of the new vertex float xi = 0, eta = 0; InsertVertexResult success; bool errorflag; badotri = badtri.poortri; borg = badotri.Org(); bdest = badotri.Dest(); bapex = badotri.Apex(); // Make sure that this triangle is still the same triangle it was // when it was tested and determined to be of bad quality. // Subsequent transformations may have made it a different triangle. if (!Otri.IsDead(badotri.triangle) && (borg == badtri.triangorg) && (bdest == badtri.triangdest) && (bapex == badtri.triangapex)) { errorflag = false; // Create a new vertex at the triangle's circumcenter. // Using the original (simpler) Steiner point location method // for mesh refinement. // TODO: NewLocation doesn't work for refinement. Why? Maybe // reset VertexType? if (behavior.fixedArea || behavior.VarArea) { newloc = Primitives.FindCircumcenter(borg, bdest, bapex, ref xi, ref eta, behavior.offconstant); } else { newloc = newLocation.FindLocation(borg, bdest, bapex, ref xi, ref eta, true, badotri); } // Check whether the new vertex lies on a triangle vertex. if (((newloc.x == borg.x) && (newloc.y == borg.y)) || ((newloc.x == bdest.x) && (newloc.y == bdest.y)) || ((newloc.x == bapex.x) && (newloc.y == bapex.y))) { if (Behavior.Verbose) { logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()"); errorflag = true; } } else { // The new vertex must be in the interior, and therefore is a // free vertex with a marker of zero. Vertex newvertex = new Vertex(newloc.x, newloc.y, 0, mesh.nextras); newvertex.type = VertexType.FreeVertex; for (int i = 0; i < mesh.nextras; i++) { // Interpolate the vertex attributes at the circumcenter. newvertex.attributes[i] = borg.attributes[i] + xi * (bdest.attributes[i] - borg.attributes[i]) + eta * (bapex.attributes[i] - borg.attributes[i]); } // Ensure that the handle 'badotri' does not represent the longest // edge of the triangle. This ensures that the circumcenter must // fall to the left of this edge, so point location will work. // (If the angle org-apex-dest exceeds 90 degrees, then the // circumcenter lies outside the org-dest edge, and eta is // negative. Roundoff error might prevent eta from being // negative when it should be, so I test eta against xi.) if (eta < xi) { badotri.LprevSelf(); } // Insert the circumcenter, searching from the edge of the triangle, // and maintain the Delaunay property of the triangulation. Osub tmp = default(Osub); success = mesh.InsertVertex(newvertex, ref badotri, ref tmp, true, true); if (success == InsertVertexResult.Successful) { newvertex.hash = mesh.hash_vtx++; newvertex.id = newvertex.hash; mesh.vertices.Add(newvertex.hash, newvertex); if (mesh.steinerleft > 0) { mesh.steinerleft--; } } else if (success == InsertVertexResult.Encroaching) { // If the newly inserted vertex encroaches upon a subsegment, // delete the new vertex. mesh.UndoVertex(); } else if (success == InsertVertexResult.Violating) { // Failed to insert the new vertex, but some subsegment was // marked as being encroached. } else { // success == DUPLICATEVERTEX // Couldn't insert the new vertex because a vertex is already there. if (Behavior.Verbose) { logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()"); errorflag = true; } } } if (errorflag) { logger.Error("The new vertex is at the circumcenter of triangle: This probably " + "means that I am trying to refine triangles to a smaller size than can be " + "accommodated by the finite precision of floating point arithmetic.", "Quality.SplitTriangle()"); throw new Exception("The new vertex is at the circumcenter of triangle."); } } }
private void SplitTriangle(BadTriangle badtri) { Point point; Otri otri = new Otri(); double num = 0; double num1 = 0; otri = badtri.poortri; Vertex vertex = otri.Org(); Vertex vertex1 = otri.Dest(); Vertex vertex2 = otri.Apex(); if (!Otri.IsDead(otri.triangle) && vertex == badtri.triangorg && vertex1 == badtri.triangdest && vertex2 == badtri.triangapex) { bool flag = false; point = (this.behavior.fixedArea || this.behavior.VarArea ? Primitives.FindCircumcenter(vertex, vertex1, vertex2, ref num, ref num1, this.behavior.offconstant) : this.newLocation.FindLocation(vertex, vertex1, vertex2, ref num, ref num1, true, otri)); if ((point.x != vertex.x || point.y != vertex.y) && (point.x != vertex1.x || point.y != vertex1.y) && (point.x != vertex2.x || point.y != vertex2.y)) { Vertex vertex3 = new Vertex(point.x, point.y, 0, this.mesh.nextras) { type = VertexType.FreeVertex }; for (int i = 0; i < this.mesh.nextras; i++) { vertex3.attributes[i] = vertex.attributes[i] + num * (vertex1.attributes[i] - vertex.attributes[i]) + num1 * (vertex2.attributes[i] - vertex.attributes[i]); } if (num1 < num) { otri.LprevSelf(); } Osub osub = new Osub(); InsertVertexResult insertVertexResult = this.mesh.InsertVertex(vertex3, ref otri, ref osub, true, true); if (insertVertexResult == InsertVertexResult.Successful) { Mesh mesh = this.mesh; int hashVtx = mesh.hash_vtx; mesh.hash_vtx = hashVtx + 1; vertex3.hash = hashVtx; vertex3.id = vertex3.hash; this.mesh.vertices.Add(vertex3.hash, vertex3); if (this.mesh.steinerleft > 0) { Mesh mesh1 = this.mesh; mesh1.steinerleft = mesh1.steinerleft - 1; } } else if (insertVertexResult == InsertVertexResult.Encroaching) { this.mesh.UndoVertex(); } else if (insertVertexResult != InsertVertexResult.Violating && Behavior.Verbose) { this.logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()"); flag = true; } } else if (Behavior.Verbose) { this.logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()"); flag = true; } if (flag) { this.logger.Error("The new vertex is at the circumcenter of triangle: This probably means that I am trying to refine triangles to a smaller size than can be accommodated by the finite precision of floating point arithmetic.", "Quality.SplitTriangle()"); throw new Exception("The new vertex is at the circumcenter of triangle."); } } }