示例#1
0
        private void AddEdge(int v0, int v1, float cost)
        {
            // remove all edges crossing our clipping edge (TODO: could we split them instead?)
            Edge         clippingEdge = new Edge(v0, v1, cost);
            Stack <Edge> candidates   = new Stack <Edge>();

            candidates.Push(clippingEdge);
            while (candidates.Count > 0)
            {
                Edge cEdge = candidates.Pop();

                bool isect = false;
                if ((vertices[cEdge.v[0]] - vertices[cEdge.v[1]]).Length() > 1e-3f)
                {
                    foreach (Edge e in edges)
                    {
                        Vertex p;
                        if (e.v[0] != cEdge.v[0] && e.v[0] != cEdge.v[1] &&
                            e.v[1] != cEdge.v[0] && e.v[1] != cEdge.v[1] &&
                            GeomUtils.SegmentIntersect(vertices[e.v[0]], vertices[e.v[1]], vertices[cEdge.v[0]], vertices[cEdge.v[1]], out p))
                        {
                            vertices.Add(p);
                            int isectIdx = vertices.Count - 1;

                            edges.Remove(e);
                            edges.Add(new Edge(e.v[0], isectIdx, e.cost));
                            edges.Add(new Edge(isectIdx, e.v[1], e.cost));

                            candidates.Push(new Edge(cEdge.v[0], isectIdx, cost));
                            candidates.Push(new Edge(isectIdx, cEdge.v[1], cost));
                            isect = true;
                            break;
                        }
                    }
                    if (!isect)
                    {
                        edges.Add(cEdge);
                    }
                }
            }
        }
示例#2
0
        public bool FlipTriangles(int tri1, int tri2, out int[] result)
        {
            Triangle triangle1 = triangles[tri1];

            Debug.Assert(triangle1.valid);
            Triangle triangle2 = triangles[tri2];

            Debug.Assert(triangle2.valid);

            int commonEdgeIdx = CommonEdge(triangle1, triangle2);

            Debug.Assert(commonEdgeIdx >= 0);
            Edge commonEdge = edges[commonEdgeIdx];

            Debug.Assert(commonEdge.triangles[0] == tri1 || commonEdge.triangles[0] == tri2);
            Debug.Assert(commonEdge.triangles[1] == tri1 || commonEdge.triangles[1] == tri2);

            // Tri1 = A,B,C
            // Tri2 = B,D,C
            // commonEdge = B,C

            int localEdgeT1 = triangle1.LocalEdgeIndex(commonEdgeIdx);

            Debug.Assert(localEdgeT1 >= 0);
            int localEdgeT2 = triangle2.LocalEdgeIndex(commonEdgeIdx);

            Debug.Assert(localEdgeT2 >= 0);

            int A = VertexOutOfTriEdge(tri1, localEdgeT1);
            int D = VertexOutOfTriEdge(tri2, localEdgeT2);

            Debug.Assert(A >= 0);
            Debug.Assert(D >= 0);

            int B = (commonEdge.triangles[0] == tri1 ? commonEdge.vertices[0] : commonEdge.vertices[1]);
            int C = (B == commonEdge.vertices[0] ? commonEdge.vertices[1] : commonEdge.vertices[0]);

            Debug.Assert(A != B && A != C && A != D && B != C && B != D && C != D);

            result = new int[2];

            if (!GeomUtils.SegmentIntersect(vertices[A], vertices[D], vertices[B], vertices[C]))
            {
                // can't flip
                result[0] = result[1] = -1;
                return(false);
            }

            float closestAngleBefore = Math.Min(ClosestAngleOnTri(A, B, C), ClosestAngleOnTri(B, D, C));

            if (!IsWorthFlipping(A, B, C, D))
            {
                // The resulting triangles would not improve the triangulation, don't bother
                return(false);
            }

            RemoveTriangle(tri1);
            RemoveTriangle(tri2);

            result[0] = CreateTriangle(A, B, D);
            result[1] = CreateTriangle(A, D, C);

            float closestAngleAfter = Math.Min(ClosestAngleOnTri(A, B, D), ClosestAngleOnTri(A, D, C));

            //Debug.Assert(closestAngleBefore < closestAngleAfter);
#if DEBUG
            Debug.Assert(CheckConsistency());
#endif
            return(true);
        }