Пример #1
0
        //Test if we should flip an edge
        //a, b, c belongs to the triangle and d is the point on the other triangle
        //a-c is the edge, which is important so we can flip it, by making the edge b-d
        public static bool ShouldFlipEdge(MyVector2 a, MyVector2 b, MyVector2 c, MyVector2 d)
        {
            bool shouldFlipEdge = false;

            //Use the circle test to test if we need to flip this edge
            //We should flip if d is inside a circle formed by a, b, c
            IntersectionCases intersectionCases = Intersections.PointCircle(a, b, c, d);

            if (intersectionCases == IntersectionCases.IsInside)
            {
                //Are these the two triangles forming a convex quadrilateral? Otherwise the edge cant be flipped
                if (Geometry.IsQuadrilateralConvex(a, b, c, d))
                {
                    //If the new triangle after a flip is not better, then dont flip
                    //This will also stop the algorithm from ending up in an endless loop
                    IntersectionCases intersectionCases2 = Intersections.PointCircle(b, c, d, a);

                    if (intersectionCases2 == IntersectionCases.IsOnEdge || intersectionCases2 == IntersectionCases.IsInside)
                    {
                        shouldFlipEdge = false;
                    }
                    else
                    {
                        shouldFlipEdge = true;
                    }
                }
            }

            return(shouldFlipEdge);
        }
        //
        // Remove the edges that intersects with a constraint by flipping triangles
        //

        //The idea here is that all possible triangulations for a set of points can be found
        //by systematically swapping the diagonal in each convex quadrilateral formed by a pair of triangles
        //So we will test all possible arrangements and will always find a triangulation which includes the constrained edge
        private static List <HalfEdge2> RemoveIntersectingEdges(MyVector2 v_i, MyVector2 v_j, Queue <HalfEdge2> intersectingEdges)
        {
            List <HalfEdge2> newEdges = new List <HalfEdge2>();

            int safety = 0;

            //While some edges still cross the constrained edge, do steps 3.1 and 3.2
            while (intersectingEdges.Count > 0)
            {
                safety += 1;

                if (safety > 100000)
                {
                    Debug.Log("Stuck in infinite loop when fixing constrained edges");

                    break;
                }

                //Step 3.1. Remove an edge from the list of edges that intersects the constrained edge
                HalfEdge2 e = intersectingEdges.Dequeue();

                //The vertices belonging to the two triangles
                MyVector2 v_k   = e.v.position;
                MyVector2 v_l   = e.prevEdge.v.position;
                MyVector2 v_3rd = e.nextEdge.v.position;
                //The vertex belonging to the opposite triangle and isn't shared by the current edge
                MyVector2 v_opposite_pos = e.oppositeEdge.nextEdge.v.position;

                //Step 3.2. If the two triangles don't form a convex quadtrilateral
                //place the edge back on the list of intersecting edges (because this edge cant be flipped)
                //and go to step 3.1
                if (!Geometry.IsQuadrilateralConvex(v_k, v_l, v_3rd, v_opposite_pos))
                {
                    intersectingEdges.Enqueue(e);

                    continue;
                }
                else
                {
                    //Flip the edge like we did when we created the delaunay triangulation
                    HalfEdgeHelpMethods.FlipTriangleEdge(e);

                    //The new diagonal is defined by the vertices
                    MyVector2 v_m = e.v.position;
                    MyVector2 v_n = e.prevEdge.v.position;

                    //If this new diagonal intersects with the constrained edge, add it to the list of intersecting edges
                    if (IsEdgeCrossingEdge(v_i, v_j, v_m, v_n))
                    {
                        intersectingEdges.Enqueue(e);
                    }
                    //Place it in the list of newly created edges
                    else
                    {
                        newEdges.Add(e);
                    }
                }
            }

            return(newEdges);
        }