//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;
            }
        }
Esempio n. 2
0
 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
        }