示例#1
0
        private static void TriangulateMonotone(Face face)
        {
            var faceVertices = new List <Vertex>();

            foreach (var vHandle in _geometry.GetFaceVertices(face.Handle))
            {
                faceVertices.Add(vHandle);
            }

            if (faceVertices.Count.Equals(3))
            {
                return;
            }

            var sortedVerts = GetSortedVertices(_geometry, face, faceVertices);
            var vertStack   = new Stack <Vertex>();
            var leftChain   = GetLeftChain(sortedVerts, face).ToList();

            vertStack.Push(sortedVerts[0]);
            vertStack.Push(sortedVerts[1]);

            for (var i = 2; i < sortedVerts.Count - 1; i++)
            {
                var current = sortedVerts[i];

                if (!IsLeftChain(leftChain, current) && IsLeftChain(leftChain, vertStack.Peek()) ||
                    IsLeftChain(leftChain, current) && !IsLeftChain(leftChain, vertStack.Peek()))
                {
                    while (vertStack.Count > 0)
                    {
                        var popped = vertStack.Pop();

                        if (vertStack.Count > 0)
                        {
                            _geometry.InsertDiagonal(current.Handle, popped.Handle);
                        }
                    }
                    vertStack.Push(sortedVerts[i - 1]);
                    vertStack.Push(current);
                }
                else
                {
                    var popped = vertStack.Pop();

                    Vertex next;
                    Vertex prev;

                    if (IsLeftChain(leftChain, popped))
                    {
                        next = sortedVerts[i];
                        prev = vertStack.Peek();
                    }
                    else
                    {
                        next = vertStack.Peek();
                        prev = sortedVerts[i];
                    }

                    while (vertStack.Count > 0 && !_geometry.IsAngleGreaterOrEqualPi(face, next, popped, prev))
                    {
                        popped = vertStack.Pop();

                        if (vertStack.Count > 0)
                        {
                            if (IsLeftChain(leftChain, popped))
                            {
                                next = sortedVerts[i];
                                prev = vertStack.Peek();
                            }
                            else
                            {
                                next = vertStack.Peek();
                                prev = sortedVerts[i];
                            }
                        }

                        _geometry.InsertDiagonal(current.Handle, popped.Handle);
                    }
                    vertStack.Push(popped);
                    vertStack.Push(current);
                }
            }

            var count = vertStack.Count;

            for (var j = 0; j < count; j++)
            {
                var popped = vertStack.Pop();

                if (j == 0)
                {
                    continue;
                }
                if (j != count - 1)
                {
                    _geometry.InsertDiagonal(sortedVerts.Last().Handle, popped.Handle);
                }
            }
        }