//Find all triangles opposite of vertex p //But we will find all edges opposite to p, and from these edges we can find the triangles private static void AddTrianglesOppositePToStack(MyVector2 p, Stack <HalfEdge2> trianglesOppositeP, HalfEdgeData2 triangulationData) { //Find a vertex at position p and then rotate around it, triangle-by-triangle, to find all opposite edges HalfEdgeVertex2 rotateAroundThis = null; foreach (HalfEdgeVertex2 v in triangulationData.vertices) { if (v.position.Equals(p)) { rotateAroundThis = v; } } //Which triangle is this vertex a part of, so we know when we have rotated all the way around HalfEdgeFace2 tStart = rotateAroundThis.edge.face; HalfEdgeFace2 tCurrent = null; int safety = 0; while (tCurrent != tStart) { safety += 1; if (safety > 10000) { Debug.Log("Stuck in endless loop when finding opposite edges in Delaunay Sloan"); break; } //The edge opposite to p HalfEdge2 edgeOppositeRotateVertex = rotateAroundThis.edge.nextEdge.oppositeEdge; //Try to add the edge to the list iof triangles we are interested in //Null might happen if we are at the border //A stack might include duplicates so we have to check for that as well if (edgeOppositeRotateVertex != null && !trianglesOppositeP.Contains(edgeOppositeRotateVertex)) { trianglesOppositeP.Push(edgeOppositeRotateVertex); } //Rotate left - this assumes we can always rotate left so no holes are allowed //and neither can we investigate one of the vertices thats a part of the supertriangle //which we dont need to worry about because p is never a part of the supertriangle rotateAroundThis = rotateAroundThis.edge.oppositeEdge.v; //In which triangle are we now? tCurrent = rotateAroundThis.edge.face; } }
public HalfEdge2(HalfEdgeVertex2 v) { this.v = v; }
// // Triangle to half-edge // public static HalfEdgeData2 Triangle2ToHalfEdge2(HashSet <Triangle2> triangles, HalfEdgeData2 data) { //Make sure the triangles have the same orientation, which is clockwise triangles = HelpMethods.OrientTrianglesClockwise(triangles); //Fill the data structure foreach (Triangle2 t in triangles) { HalfEdgeVertex2 v1 = new HalfEdgeVertex2(t.p1); HalfEdgeVertex2 v2 = new HalfEdgeVertex2(t.p2); HalfEdgeVertex2 v3 = new HalfEdgeVertex2(t.p3); //The vertices the edge points to HalfEdge2 he1 = new HalfEdge2(v1); HalfEdge2 he2 = new HalfEdge2(v2); HalfEdge2 he3 = new HalfEdge2(v3); he1.nextEdge = he2; he2.nextEdge = he3; he3.nextEdge = he1; he1.prevEdge = he3; he2.prevEdge = he1; he3.prevEdge = he2; //The vertex needs to know of an edge going from it v1.edge = he2; v2.edge = he3; v3.edge = he1; //The face the half-edge is connected to HalfEdgeFace2 face = new HalfEdgeFace2(he1); //Each edge needs to know of the face connected to this edge he1.face = face; he2.face = face; he3.face = face; //Add everything to the lists data.edges.Add(he1); data.edges.Add(he2); data.edges.Add(he3); data.faces.Add(face); data.vertices.Add(v1); data.vertices.Add(v2); data.vertices.Add(v3); } //Step 4. Find the half-edges going in the opposite direction of each edge we have //Is there a faster way to do this because this is the bottleneck? foreach (HalfEdge2 e in data.edges) { HalfEdgeVertex2 goingToVertex = e.v; HalfEdgeVertex2 goingFromVertex = e.prevEdge.v; foreach (HalfEdge2 eOther in data.edges) { //Dont compare with itself if (e == eOther) { continue; } //Is this edge going between the vertices in the opposite direction if (goingFromVertex.position.Equals(eOther.v.position) && goingToVertex.position.Equals(eOther.prevEdge.v.position)) { e.oppositeEdge = eOther; break; } } } return(data); }
//Create a new triangle face when splitting triangle face private static void CreateNewFace(HalfEdge2 e_old, MyVector2 splitPosition, HalfEdgeData2 data, HashSet <HalfEdge2> newEdges) { //This triangle has the following positons MyVector2 p_split = splitPosition; MyVector2 p_next = e_old.prevEdge.v.position; MyVector2 p_prev = e_old.v.position; //Create the new stuff HalfEdgeVertex2 v_split = new HalfEdgeVertex2(p_split); HalfEdgeVertex2 v_next = new HalfEdgeVertex2(p_next); HalfEdgeVertex2 v_prev = new HalfEdgeVertex2(p_prev); //This is the edge that has the same position as the old edge HalfEdge2 e_1 = new HalfEdge2(v_prev); HalfEdge2 e_2 = new HalfEdge2(v_split); HalfEdge2 e_3 = new HalfEdge2(v_next); //The new face HalfEdgeFace2 f = new HalfEdgeFace2(e_1); //Create the connections //The new edge e has the same opposite as the old edge e_1.oppositeEdge = e_old.oppositeEdge; //But the opposite edge needs a new reference to this edge if its not a border if (e_1.oppositeEdge != null) { e_old.oppositeEdge.oppositeEdge = e_1; } //The other new edges will find the opposite in a loop when we have created all new edges newEdges.Add(e_2); newEdges.Add(e_3); //Create the connections between the edges e_1.nextEdge = e_2; e_1.prevEdge = e_3; e_2.nextEdge = e_3; e_2.prevEdge = e_1; e_3.nextEdge = e_1; e_3.prevEdge = e_2; //Each edge needs to connect to a face e_1.face = f; e_2.face = f; e_3.face = f; //The vertices need an edge that starts at that point v_split.edge = e_3; v_next.edge = e_1; v_prev.edge = e_2; //Add them to the lists data.faces.Add(f); data.edges.Add(e_1); data.edges.Add(e_2); data.edges.Add(e_3); data.vertices.Add(v_split); data.vertices.Add(v_next); data.vertices.Add(v_prev); }
// // Flip triangle edge // //So the edge shared by two triangles is going between the two other vertices originally not part of the edge public static void FlipTriangleEdge(HalfEdge2 e) { //The data we need //This edge's triangle edges HalfEdge2 e_1 = e; HalfEdge2 e_2 = e_1.nextEdge; HalfEdge2 e_3 = e_1.prevEdge; //The opposite edge's triangle edges HalfEdge2 e_4 = e_1.oppositeEdge; HalfEdge2 e_5 = e_4.nextEdge; HalfEdge2 e_6 = e_4.prevEdge; //The 4 vertex positions MyVector2 aPos = e_1.v.position; MyVector2 bPos = e_2.v.position; MyVector2 cPos = e_3.v.position; MyVector2 dPos = e_5.v.position; //The 6 old vertices, we can use HalfEdgeVertex2 a_old = e_1.v; HalfEdgeVertex2 b_old = e_1.nextEdge.v; HalfEdgeVertex2 c_old = e_1.prevEdge.v; HalfEdgeVertex2 a_opposite_old = e_4.prevEdge.v; HalfEdgeVertex2 c_opposite_old = e_4.v; HalfEdgeVertex2 d_old = e_4.nextEdge.v; //Flip //Vertices //Triangle 1: b-c-d HalfEdgeVertex2 b = b_old; HalfEdgeVertex2 c = c_old; HalfEdgeVertex2 d = d_old; //Triangle 1: b-d-a HalfEdgeVertex2 b_opposite = a_opposite_old; b_opposite.position = bPos; HalfEdgeVertex2 d_opposite = c_opposite_old; d_opposite.position = dPos; HalfEdgeVertex2 a = a_old; //Change half-edge - half-edge connections e_1.nextEdge = e_3; e_1.prevEdge = e_5; e_2.nextEdge = e_4; e_2.prevEdge = e_6; e_3.nextEdge = e_5; e_3.prevEdge = e_1; e_4.nextEdge = e_6; e_4.prevEdge = e_2; e_5.nextEdge = e_1; e_5.prevEdge = e_3; e_6.nextEdge = e_2; e_6.prevEdge = e_4; //Half-edge - vertex connection e_1.v = b; e_2.v = b_opposite; e_3.v = c; e_4.v = d_opposite; e_5.v = d; e_6.v = a; //Half-edge - face connection HalfEdgeFace2 f1 = e_1.face; HalfEdgeFace2 f2 = e_4.face; e_1.face = f1; e_3.face = f1; e_5.face = f1; e_2.face = f2; e_4.face = f2; e_6.face = f2; //Face - half-edge connection f1.edge = e_3; f2.edge = e_4; //Vertices connection, which should have a reference to a half-edge going away from the vertex //Triangle 1: b-c-d b.edge = e_3; c.edge = e_5; d.edge = e_1; //Triangle 1: b-d-a b_opposite.edge = e_4; d_opposite.edge = e_6; a.edge = e_2; //Opposite-edges are not changing! //And neither are we adding, removing data so we dont need to update the lists with all data }