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); } } }