internal CdtFrontElement(CdtSite leftSite, CdtEdge edge) {
     Debug.Assert(edge.upperSite.Point.X != edge.lowerSite.Point.X &&
                  edge.upperSite.Point.X < edge.lowerSite.Point.X && leftSite == edge.upperSite ||
                  edge.upperSite.Point.X > edge.lowerSite.Point.X && leftSite == edge.lowerSite);
     RightSite = edge.upperSite == leftSite ? edge.lowerSite : edge.upperSite;
     LeftSite = leftSite;
     Edge = edge;
 }
예제 #2
0
 CdtSite AddSite(Point point, object relatedObject) {
     CdtSite site;
     if (PointsToSites.TryGetValue(point, out site)) {
         site.Owner = relatedObject;//set the owner anyway
         return site;
     }
     PointsToSites[point] = site = new CdtSite(point) { Owner = relatedObject };
     return site;
 }
 public EdgeTracer(CdtEdge edge, Set<CdtTriangle> triangles, RbTree<CdtFrontElement> front, List<CdtSite> leftPolygon, List<CdtSite> rightPolygon) {
     this.edge = edge;
     this.triangles = triangles;
     this.front = front;
     this.leftPolygon = leftPolygon;
     this.rightPolygon = rightPolygon;
     a = edge.upperSite;
     b = edge.lowerSite;
 }
 //
 internal CdtTriangle(CdtSite aLeft, CdtSite aRight, CdtSite bRight, CdtEdge a, CdtEdge b, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) {
    // Debug.Assert(Point.GetTriangleOrientation(aLeft.Point, aRight.Point, bRight.Point) == TriangleOrientation.Counterclockwise);
     Sites[0] = aLeft;
     Sites[1] = aRight;
     Sites[2] = bRight;
     Edges[0] = a;
     Edges[1] = b;
     BindEdgeToTriangle(aLeft, a);
     BindEdgeToTriangle(aRight, b);
     CreateEdge(2, createEdgeDelegate);
 }
 internal CdtSweeper(List<CdtSite> listOfSites, CdtSite p_1, CdtSite p_2, 
     Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) {
     this.listOfSites=listOfSites;
     var firstTriangle=new CdtTriangle(p_1, p_2, listOfSites[0], createEdgeDelegate);
     Triangles.Insert( firstTriangle );
     front.Insert(new CdtFrontElement(p_1, firstTriangle.Edges[2] ));
     front.Insert(new CdtFrontElement(listOfSites[0], firstTriangle.Edges[1]));
     this.p_1 = p_1;
     this.p_2 = p_2;
     this.createEdgeDelegate = createEdgeDelegate;
     //ShowFront();
 }
 internal CdtTriangle(CdtSite a, CdtSite b, CdtSite c, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) {
     var orientation = Point.GetTriangleOrientationWithNoEpsilon(a.Point, b.Point, c.Point);
     switch (orientation) {
         case TriangleOrientation.Counterclockwise:
             FillCcwTriangle(a, b, c, createEdgeDelegate);
             break;
         case TriangleOrientation.Clockwise:
             FillCcwTriangle(a, c, b, createEdgeDelegate);
             break;
         default: throw new InvalidOperationException();
     }
 }
예제 #7
0
 void ProcessSite(CdtSite site)
 {
     PointEvent(site);
     //ShowFrontWithSite(site);
     for (int i = 0; i < site.Edges.Count; i++)
     {
         var edge = site.Edges[i];
         if (edge.Constrained)
         {
             EdgeEvent(edge);
         }
     }
     // TestThatFrontIsConnected();
 }
예제 #8
0
        List <DebugCurve> ShowIllegalEdge(CdtEdge edge, CdtSite pi, int i)
        {
            List <DebugCurve> ls = new List <DebugCurve>();

            ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point)));
            for (int j = 0; j < 3; j++)
            {
                var ee = edge.CcwTriangle.Edges[j];
                ls.Add(new DebugCurve(j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point)));
            }
            ls.Add(new DebugCurve(100, 1, "black", Circumcircle(edge.CcwTriangle.Sites[0].Point, edge.CcwTriangle.Sites[1].Point, edge.CcwTriangle.Sites[2].Point)));
            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
            return(ls);
        }
예제 #9
0
//        void ShowDebug(IEnumerable<CdtTriangle> cdtTriangles, CdtEdge cdtEdge, CdtTriangle cdtTriangle) {
//            var l = new List<DebugCurve> { new DebugCurve(10,"red",new LineSegment(start,end)) };
//            if(cdtEdge!=null)
//                l.Add(new DebugCurve(100,3,"navy", new LineSegment(cdtEdge.upperSite.Point,cdtEdge.lowerSite.Point)));
//            AddTriangleToListOfDebugCurves(l,cdtTriangle,100,2,"brown");
//            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
//
//        }
//        static void AddTriangleToListOfDebugCurves(List<DebugCurve> debugCurves,CdtTriangle triangle,byte transparency,double width,string color) {
//            foreach(var cdtEdge in triangle.Edges) {
//                debugCurves.Add(new DebugCurve(transparency,width,color,new LineSegment(cdtEdge.upperSite.Point,cdtEdge.lowerSite.Point)));
//            }
//        }

        internal int GetHyperplaneSign(CdtSite cdtSite)
        {
            var area = Point.SignedDoubledTriangleArea(start, cdtSite.Point, end);

            if (area > ApproximateComparer.DistanceEpsilon)
            {
                return(1);
            }
            if (area < -ApproximateComparer.DistanceEpsilon)
            {
                return(-1);
            }
            return(0);
        }
        internal CdtSweeper(List <CdtSite> listOfSites, CdtSite p_1, CdtSite p_2,
                            Func <CdtSite, CdtSite, CdtEdge> createEdgeDelegate)
        {
            this.listOfSites = listOfSites;
            var firstTriangle = new CdtTriangle(p_1, p_2, listOfSites[0], createEdgeDelegate);

            Triangles.Insert(firstTriangle);
            front.Insert(new CdtFrontElement(p_1, firstTriangle.Edges[2]));
            front.Insert(new CdtFrontElement(listOfSites[0], firstTriangle.Edges[1]));
            this.p_1 = p_1;
            this.p_2 = p_2;
            this.createEdgeDelegate = createEdgeDelegate;
            //ShowFront();
        }
예제 #11
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
        CdtSite AddSite(Point point, object relatedObject)
        {
            CdtSite site;

            if (PointsToSites.TryGetValue(point, out site))
            {
                site.Owner = relatedObject;//set the owner anyway
                return(site);
            }
            PointsToSites[point] = site = new CdtSite(point)
            {
                Owner = relatedObject
            };
            return(site);
        }
예제 #12
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
        void AddP1AndP2()
        {
            var box = Rectangle.CreateAnEmptyBox();

            foreach (var site in PointsToSites.Keys)
            {
                box.Add(site);
            }

            var delx = box.Width / 3;
            var dely = box.Height / 3;

            P1 = new CdtSite(box.LeftBottom + new Point(-delx, -dely));
            P2 = new CdtSite(box.RightBottom + new Point(delx, -dely));
        }
예제 #13
0
//        int count;
//         bool db { get { return count == 147; } }
        void PointEvent(CdtSite pi)
        {
            RBNode <CdtFrontElement> hittedFrontElementNode;

            ProjectToFront(pi, out hittedFrontElementNode);
            CdtSite rightSite;
            CdtSite leftSite = hittedFrontElementNode.Item.X + ApproximateComparer.DistanceEpsilon < pi.Point.X
                                   ? MiddleCase(pi, hittedFrontElementNode, out rightSite)
                                   : LeftCase(pi, hittedFrontElementNode, out rightSite);
            var piNode = InsertSiteIntoFront(leftSite, pi, rightSite);

            TriangulateEmptySpaceToTheRight(piNode);
            piNode = FindNodeInFrontBySite(front, leftSite);
            TriangulateEmptySpaceToTheLeft(piNode);
        }
예제 #14
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
        /// <summary>
        /// compare first y then -x coordinates
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns>1 if a is above b, 0 if points are the same and -1 if a is below b</returns>
        static internal int Above(CdtSite a, CdtSite b)
        {
            var del = a.Point.Y - b.Point.Y;

            if (del > 0)
            {
                return(1);
            }
            if (del < 0)
            {
                return(-1);
            }
            del = a.Point.X - b.Point.X;
            return(del > 0 ? -1 : (del < 0 ? 1 : 0)); //for a horizontal edge the point with the smaller X is the upper point
        }
예제 #15
0
 void LegalizeEdge(CdtSite pi, CdtEdge edge)
 {
     Debug.Assert(pi != edge.upperSite && pi != edge.lowerSite);
     if (edge.Constrained || edge.CcwTriangle == null || edge.CwTriangle == null)
     {
         return;
     }
     if (edge.CcwTriangle.Contains(pi))
     {
         LegalizeEdgeForOtherCwTriangle(pi, edge);
     }
     else
     {
         LegalizeEdgeForOtherCcwTriangle(pi, edge);
     }
 }
예제 #16
0
        //        /// <summary>
        //        /// returns CdtEdges crossed by the segment a.Point, b.Point
        //        /// </summary>
        //        /// <param name="prevA">if prevA is not a null, that means the path is passing through prevA and might need to include
        //        /// the edge containing a.Point if such exists</param>
        //        /// <param name="a"></param>
        //        /// <param name="b"></param>
        //        /// <returns></returns>
        //        internal IEnumerable<CdtEdge> GetCdtEdgesCrossedBySegment(PolylinePoint prevA, PolylinePoint a, PolylinePoint b) {
        //            count++;
        //            if (dd) {
        //                var l = new List<DebugCurve> {
        //                                                 new DebugCurve("red", new Ellipse(5, 5, a.Point)),
        //                                                 new DebugCurve("blue", new Ellipse(5, 5, b.Point)),
        //                                                 new DebugCurve("blue", new LineSegment(a.Point, b.Point))
        //                                             };
        //
        //                l.AddRange(
        //                    GetTriangles().Select(
        //                        tr => new DebugCurve(100, 1, "green", new Polyline(tr.Sites.Select(v => v.Point)) {Closed = true})));
        //                LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
        //
        //            }
        //            var ret = new List<CdtEdge>();
        //            CdtEdge piercedEdge;
        //            CdtTriangle t = GetFirstTriangleAndPiercedEdge(a, b, out piercedEdge);
        //            if (ProperCrossing(a, b, piercedEdge))
        //                ret.Add(piercedEdge);
        //
        //            ret.AddRange(ContinueThreadingThroughTriangles(a,b,t, piercedEdge));
        //
        //            return ret;
        //        }

        /*
         *      static bool ProperCrossing(Point a, Point b, CdtEdge cdtEdge) {
         *          return cdtEdge != null && cdtEdge.upperSite.Owner != cdtEdge.lowerSite.Owner &&
         *                 CrossEdgeInterior(cdtEdge, a, b);
         *      }
         */
        //        static int count;
        //        static bool db { get { return count == 125; }}

        internal IEnumerable <CdtEdge> ThreadEdgeThroughTriangles(CdtSite startSite, Point end)
        {
            CdtEdge piercedEdge;
            var     triangle = FindFirstPiercedTriangle(startSite, end, out piercedEdge);

            if (triangle == null)
            {
                yield break;
            }

            var start = startSite.Point;

            foreach (var cdtEdge in ThreadThroughTriangles(start, end, triangle, piercedEdge))
            {
                yield return(cdtEdge);
            }
        }
        /// <summary>
        /// Determines the edges of the triangulation together with their desired length (distance between nodes).
        /// </summary>
        /// <param name="originalGraph"></param>
        /// <param name="cdt"></param>
        /// <param name="targetSizes"></param>
        /// <param name="desiredEdgeDistances"></param>
        /// <returns></returns>
        public static int GetProximityEdgesWithDistance(GeometryGraph originalGraph, Cdt cdt,
                                                        Size[] targetSizes,
                                                        out List <Tuple <int, int, double, double> > desiredEdgeDistances)
        {
            desiredEdgeDistances = new List <Tuple <int, int, double, double> >();
            int numberOverlappingPairs = 0;
            var edgeSet = new HashSet <CdtEdge>();

            //add edges
            foreach (CdtTriangle triangle in cdt.GetTriangles())
            {
                foreach (CdtEdge triangleEdge in triangle.Edges)
                {
                    CdtSite site1   = triangleEdge.upperSite;
                    CdtSite site2   = triangleEdge.lowerSite;
                    var     nodeId1 = (int)site1.Owner;
                    var     nodeId2 = (int)site2.Owner;
                    if (edgeSet.Contains(triangleEdge))
                    {
                        continue;                                 //edge already included
                    }
                    edgeSet.Add(triangleEdge);

                    Point point1 = site1.Point;
                    Point point2 = site2.Point;

                    double t;
                    double distance = GetIdealDistanceBetweenNodes(nodeId1, nodeId2, point1, point2, targetSizes,
                                                                   out t);
                    if (t > 1)
                    {
                        numberOverlappingPairs++;
                    }
                    int nodeIdSmall = nodeId1;
                    int nodeIdBig   = nodeId2;
                    if (nodeId1 > nodeId2)
                    {
                        nodeIdSmall = nodeId2;
                        nodeIdBig   = nodeId1;
                    }
                    var tuple = new Tuple <int, int, double, double>(nodeIdSmall, nodeIdBig, distance, t);
                    desiredEdgeDistances.Add(tuple);
                }
            }
            return(numberOverlappingPairs);
        }
        internal CdtTriangle(CdtSite a, CdtSite b, CdtSite c, Func <CdtSite, CdtSite, CdtEdge> createEdgeDelegate)
        {
            var orientation = Point.GetTriangleOrientationWithNoEpsilon(a.Point, b.Point, c.Point);

            switch (orientation)
            {
            case TriangleOrientation.Counterclockwise:
                FillCcwTriangle(a, b, c, createEdgeDelegate);
                break;

            case TriangleOrientation.Clockwise:
                FillCcwTriangle(a, c, b, createEdgeDelegate);
                break;

            default: throw new InvalidOperationException();
            }
        }
예제 #19
0
        static void ShowFlip(CdtSite pi, CdtTriangle t, CdtTriangle ot)
        {
            List <DebugCurve> ls = new List <DebugCurve>();

            ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point)));
            for (int i = 0; i < 3; i++)
            {
                var e = t.Edges[i];
                ls.Add(new DebugCurve(100, 1, "red", new LineSegment(e.upperSite.Point, e.lowerSite.Point)));
            }
            for (int i = 0; i < 3; i++)
            {
                var e = ot.Edges[i];
                ls.Add(new DebugCurve(100, 1, "blue", new LineSegment(e.upperSite.Point, e.lowerSite.Point)));
            }
            ls.Add(new DebugCurve(Circumcircle(t.Sites[0].Point, t.Sites[1].Point, t.Sites[2].Point)));
            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
        }
 internal CdtTriangle(CdtSite pi, CdtEdge edge, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) {
     switch (Point.GetTriangleOrientationWithNoEpsilon(edge.upperSite.Point, edge.lowerSite.Point, pi.Point)) {
         case TriangleOrientation.Counterclockwise:
             edge.CcwTriangle = this;
             Sites[0] = edge.upperSite;
             Sites[1] = edge.lowerSite;
             break;
         case TriangleOrientation.Clockwise:
             edge.CwTriangle = this;
             Sites[0] = edge.lowerSite;
             Sites[1] = edge.upperSite;
             break;
         default:
             throw new InvalidOperationException();
     }
     Edges[0] = edge;
     Sites[2] = pi;
     CreateEdge(1, createEdgeDelegate);
     CreateEdge(2, createEdgeDelegate);
 }
예제 #21
0
        CdtSite LeftCase(CdtSite pi, RBNode <CdtFrontElement> hittedFrontElementNode, out CdtSite rightSite)
        {
            //left case
            //                if(db)ShowFrontWithSite(pi, new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.upperSite.Point), new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.lowerSite.Point));
            Debug.Assert(ApproximateComparer.Close(pi.Point.X, hittedFrontElementNode.Item.X));
            var hittedFrontElement = hittedFrontElementNode.Item;

            InsertAndLegalizeTriangle(pi, hittedFrontElement);
            var prevToHitted = front.Previous(hittedFrontElementNode);
            var leftSite     = prevToHitted.Item.LeftSite;

            rightSite = hittedFrontElementNode.Item.RightSite;
            //                if(db)ShowFrontWithSite(pi, new LineSegment(pi.Point, leftSite.Point), new LineSegment(pi.Point, prevToHitted.Item.RightSite.Point));
            InsertAndLegalizeTriangle(pi, prevToHitted.Item);
            front.DeleteNodeInternal(prevToHitted);
            var d = front.Remove(hittedFrontElement);

            Debug.Assert(d != null);
            return(leftSite);
        }
예제 #22
0
        CdtTriangle FindFirstPiercedTriangle(CdtSite startSite, Point target, out CdtEdge piercedEdge)
        {
            if (startSite != null)
            {
                foreach (var t in startSite.Triangles)
                {
                    piercedEdge = GetPiercedEdgeInSiteTriangle(t, startSite, target);
                    if (piercedEdge != null)
                    {
                        if (!PointIsInsideOfTriangle(target, t))
                        {
                            return(t);
                        }
                    }
                }
            }

            piercedEdge = null;
            return(null);
        }
        void TriangulatePolygon(int start, int end, List<CdtSite> polygon, CdtSite a, CdtSite b, bool reverseTrangleWhenCompare) {
//            if(CdtSweeper.db)
//               CdtSweeper.ShowFront(triangles,front, Enumerable.Range(start, end-start+1).Select(i=> new Ellipse(10,10,polygon[i].Point)).ToArray(), new[]{new LineSegment(a.Point,b.Point)});
            var c = polygon[start];
            int cIndex = start;
            for (int i = start + 1; i <= end; i++) {
                var v = polygon[i];
                if (LocalInCircle(v, a, b, c, reverseTrangleWhenCompare)) {
                    cIndex = i;
                    c = v;
                }
            }
            var t = new CdtTriangle(a, b, c, createEdgeDelegate);
            triangles.Insert(t);
            addedTriangles.Add(t);
            if (start < cIndex)
                TriangulatePolygon(start, cIndex - 1, polygon, a, c, reverseTrangleWhenCompare);
            if (cIndex < end)
                TriangulatePolygon(cIndex + 1, end, polygon, c, b, reverseTrangleWhenCompare);
        }
예제 #24
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
 static internal CdtEdge GetOrCreateEdge(CdtSite a, CdtSite b)
 {
     if (Above(a.Point, b.Point) == 1)
     {
         var e = a.EdgeBetweenUpperSiteAndLowerSite(b);
         if (e != null)
         {
             return(e);
         }
         return(CreateEdgeOnOrderedCouple(a, b));
     }
     else
     {
         var e = b.EdgeBetweenUpperSiteAndLowerSite(a);
         if (e != null)
         {
             return(e);
         }
         return(CreateEdgeOnOrderedCouple(b, a));
     }
 }
예제 #25
0
//      /// <summary>
//      /// Testing that s in inside of the circumcircle of (p,q,r).
//      /// The good explanation of this test is in
//      /// "Guibas, Stolfi,"Primitives for the Manipulation of General Subdivisions and the Computation of Voronoi Diagrams
//      ///
//      /// </summary>
//      /// <param name="s"></param>
//      /// <param name="p"></param>
//      /// <param name="q"></param>
//      /// <param name="r"></param>
//      /// <param name="ccc"></param>
//      /// <returns></returns>
//        public static bool InCircle0(CdtSite s, CdtSite p, CdtSite q, CdtSite r, double ccc) {
//          Debug.Assert(Point.GetTriangleOrientationWithNoEpsilon(p.Point, q.Point, r.Point) == TriangleOrientation.Counterclockwise);
//          /*
//             * det(p.x,p.y, p*p,1
//             *     q.x,q.y, q*q,1
//             *     r.x,r.y, r*r,1
//             *     s.x,s.y, s*s,1) > 0
//             */
//
//          var a = p.Point.X;
//          var b = p.Point.Y;
//          var c = a*a + b*b;
//          var d = q.Point.X;
//          var e = q.Point.Y;
//          var f = d*d + e*e;
//          var g = r.Point.X;
//          var h = r.Point.Y;
//          var k = g*g + h*h;
//          var l = s.Point.X;
//          var m = s.Point.Y;
//          var n = l*l + m*m;
//
//
//
//          double ddd = ccc - ((a - d) * (h * n - k * m) + (e - b) * (g * n - k * l) + (c - f) * (g * m - h * l) +
//                                   (g - l) * (b * f - c * e) + (m - h) * (a * f - c * d) + (k - n) * (a * e - b * d));
//          if (Math.Abs(ddd) > diff) {
//              diff = ddd;
//              Console.WriteLine(diff);
//          }
//          return (a - d)*(h*n - k*m) + (e - b)*(g*n - k*l) + (c - f)*(g*m - h*l) +
//                 (g - l)*(b*f - c*e) + (m - h)*(a*f - c*d) + (k - n)*(a*e - b*d) > ApproximateComparer.Tolerance;
//      }

        /// <summary>
        /// Testing that d in inside of the circumcircle of (a,b,c).
        /// The good explanation of this test is in
        /// "Guibas, Stolfi,"Primitives for the Manipulation of General Subdivisions and the Computation of Voronoi Diagrams
        ///
        /// </summary>
        /// <param name="d"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public static bool InCircle(CdtSite d, CdtSite a, CdtSite b, CdtSite c)
        {
            Debug.Assert(Point.GetTriangleOrientationWithNoEpsilon(a.Point, b.Point, c.Point) == TriangleOrientation.Counterclockwise);

            /*
             *  | ax-dx ay-dy (ax-dx)^2+(ay-dy)^2|
             *  | bx-dx by-dy (bx-dx)^2+(by-dy)^2|
             *  | cx-dx cy-dy (cx-dx)^2+(cy-dy)^2|
             */
            var axdx = a.Point.X - d.Point.X;
            var aydy = a.Point.Y - d.Point.Y;
            var bxdx = b.Point.X - d.Point.X;
            var bydy = b.Point.Y - d.Point.Y;
            var cxdx = c.Point.X - d.Point.X;
            var cydy = c.Point.Y - d.Point.Y;
            var t0   = axdx * axdx + aydy * aydy;
            var t1   = bxdx * bxdx + bydy * bydy;
            var t2   = cxdx * cxdx + cydy * cydy;

            return(axdx * (bydy * t2 - cydy * t1) - bxdx * (aydy * t2 - cydy * t0) + cxdx * (aydy * t1 - bydy * t0) > ApproximateComparer.Tolerance);
        }
예제 #26
0
        void RegularStepFromSite(CdtSite site)
        {
            CdtTriangle triangle = null;

            foreach (var t in site.Triangles)
            {
                int index = t.Sites.Index(site);
                if (PointIsInsideCone(segEnd.Point, site.Point, t.Sites[index + 2].Point, t.Sites[index + 1].Point))
                {
                    triangle = t;
                    var segEndOrientation = Point.GetTriangleOrientation(segEnd.Point, t.Sites[index + 1].Point,
                                                                         t.Sites[index + 2].Point);
                    if (segEndOrientation != TriangleOrientation.Counterclockwise)
                    {
                        CrossTriangleEdge(t.OppositeEdge(site));
                        return;
                    }
                }
            }
            if (triangle == null)
            {
                lastCrossedFeature = OutsideOfTriangulation;
                return;
            }
            if (PointBelongsToInteriorOfTriangle(segEnd.Point, triangle))
            {
                lastCrossedFeature = triangle;
            }
            else
            {
                foreach (var e in triangle.Edges.Where(e => e.IsAdjacent(site)))
                {
                    if (Point.GetTriangleOrientation(e.upperSite.Point, e.lowerSite.Point, segEnd.Point) == TriangleOrientation.Collinear)
                    {
                        lastCrossedFeature = e;
                        return;
                    }
                }
            }
        }
예제 #27
0
        void ShowFrontWithSite(CdtSite site, params ICurve[] redCurves)
        {
            var ls = new List <DebugCurve>();


            if (site.Edges != null)
            {
                foreach (var e in site.Edges)
                {
                    ls.Add(new DebugCurve(100, 0.001, e.Constrained?"pink":"brown", new LineSegment(e.upperSite.Point, e.lowerSite.Point)));
                }
            }

            ls.Add(new DebugCurve(100, 0.01, "brown", new Ellipse(0.5, 0.5, site.Point)));

            foreach (var t in Triangles)
            {
                for (int i = 0; i < 3; i++)
                {
                    var e = t.Edges[i];
                    ls.Add(new DebugCurve(e.Constrained?(byte)150:(byte)50, e.Constrained?0.002:0.001, e.Constrained? "pink":"navy", new LineSegment(e.upperSite.Point, e.lowerSite.Point)));
                }
            }

            foreach (var c in redCurves)
            {
                ls.Add(new DebugCurve(100, 0.005, "red", c));
            }


            foreach (var frontElement in front)
            {
                ls.Add(new DebugCurve(100, 0.005, "green",
                                      new LineSegment(frontElement.Edge.upperSite.Point,
                                                      frontElement.Edge.lowerSite.Point)));
            }

            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
        }
예제 #28
0
        RBNode <CdtFrontElement> InsertSiteIntoFront(CdtSite leftSite, CdtSite pi, CdtSite rightSite)
        {
            CdtEdge leftEdge = null, rightEdge = null;

            foreach (var edge in pi.Edges)
            {
                if (leftEdge == null && edge.lowerSite == leftSite)
                {
                    leftEdge = edge;
                }
                if (rightEdge == null && edge.lowerSite == rightSite)
                {
                    rightEdge = edge;
                }
                if (leftEdge != null && rightEdge != null)
                {
                    break;
                }
            }
            Debug.Assert(leftEdge != null && rightEdge != null);
            front.Insert(new CdtFrontElement(leftSite, leftEdge));
            return(front.Insert(new CdtFrontElement(pi, rightEdge)));
        }
예제 #29
0
 void InsertAndLegalizeTriangle(CdtSite pi, CdtFrontElement frontElement)
 {
     if (Point.GetTriangleOrientationWithNoEpsilon(pi.Point, frontElement.LeftSite.Point, frontElement.RightSite.Point) != TriangleOrientation.Collinear)
     {
         var tr = new CdtTriangle(pi, frontElement.Edge, createEdgeDelegate);
         Triangles.Insert(tr);
         LegalizeEdge(pi, tr.Edges[0]);
     }
     else     //we need to split the triangle below the element in to two triangles and legalize the old edges
     //we also delete, that is forget, the frontElement.Edge
     {
         var e = frontElement.Edge;
         e.upperSite.Edges.Remove(e);
         var t            = e.CcwTriangle ?? e.CwTriangle;
         var oppositeSite = t.OppositeSite(e);
         RemoveTriangleButLeaveEdges(triangles, t);
         t = new CdtTriangle(frontElement.LeftSite, oppositeSite, pi, createEdgeDelegate);
         var t1 = new CdtTriangle(frontElement.RightSite, oppositeSite, pi, createEdgeDelegate);
         triangles.Insert(t);
         triangles.Insert(t1);
         LegalizeEdge(pi, t.OppositeEdge(pi));
         LegalizeEdge(pi, t1.OppositeEdge(pi));
     }
 }
        internal CdtTriangle(CdtSite pi, CdtEdge edge, Func <CdtSite, CdtSite, CdtEdge> createEdgeDelegate)
        {
            switch (Point.GetTriangleOrientationWithNoEpsilon(edge.upperSite.Point, edge.lowerSite.Point, pi.Point))
            {
            case TriangleOrientation.Counterclockwise:
                edge.CcwTriangle = this;
                Sites[0]         = edge.upperSite;
                Sites[1]         = edge.lowerSite;
                break;

            case TriangleOrientation.Clockwise:
                edge.CwTriangle = this;
                Sites[0]        = edge.lowerSite;
                Sites[1]        = edge.upperSite;
                break;

            default:
                throw new InvalidOperationException();
            }
            Edges[0] = edge;
            Sites[2] = pi;
            CreateEdge(1, createEdgeDelegate);
            CreateEdge(2, createEdgeDelegate);
        }
 internal CdtEdge OppositeEdge(CdtSite pi) {
     var index = Sites.Index(pi);
     Debug.Assert(index != -1);
     return Edges[index + 1];
 }
 /// <summary>
 /// here a,b,c comprise a ccw triangle
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <param name="c"></param>
 /// <param name="createEdgeDelegate"></param>
 void FillCcwTriangle(CdtSite a, CdtSite b, CdtSite c, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) {
     Sites[0] = a; Sites[1] = b; Sites[2] = c;
     for (int i = 0; i < 3; i++)
         CreateEdge(i, createEdgeDelegate);
 }
 internal bool Contains(CdtSite cdtSite) {
     return Sites.Contains(cdtSite);
 }
 void ShowIllegalEdge(CdtEdge edge, int i, CdtSite pi) {
     List<DebugCurve> ls=new List<DebugCurve>();
     ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point)));
     for(int j=0;j<3;j++) {
         var ee=edge.CwTriangle.Edges[j];
         ls.Add(new DebugCurve(j==i?"red":"blue", new LineSegment(ee.upperSite.Point,ee.lowerSite.Point)));
     }
     LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
 }
 void AddSiteToLeftPolygon(CdtSite site)
 {
     AddSiteToPolygonWithCheck(site, leftPolygon);
 }
//      /// <summary>
//      /// Testing that s in inside of the circumcircle of (p,q,r). 
//      /// The good explanation of this test is in 
//      /// "Guibas, Stolfi,"Primitives for the Manipulation of General Subdivisions and the Computation of Voronoi Diagrams
//      /// 
//      /// </summary>
//      /// <param name="s"></param>
//      /// <param name="p"></param>
//      /// <param name="q"></param>
//      /// <param name="r"></param>
//      /// <param name="ccc"></param>
//      /// <returns></returns>
//        public static bool InCircle0(CdtSite s, CdtSite p, CdtSite q, CdtSite r, double ccc) {
//          Debug.Assert(Point.GetTriangleOrientationWithNoEpsilon(p.Point, q.Point, r.Point) == TriangleOrientation.Counterclockwise);
//          /*
//             * det(p.x,p.y, p*p,1
//             *     q.x,q.y, q*q,1
//             *     r.x,r.y, r*r,1
//             *     s.x,s.y, s*s,1) > 0
//             */
//
//          var a = p.Point.X;
//          var b = p.Point.Y;
//          var c = a*a + b*b;
//          var d = q.Point.X;
//          var e = q.Point.Y;
//          var f = d*d + e*e;
//          var g = r.Point.X;
//          var h = r.Point.Y;
//          var k = g*g + h*h;
//          var l = s.Point.X;
//          var m = s.Point.Y;
//          var n = l*l + m*m;
//
//
//
//          double ddd = ccc - ((a - d) * (h * n - k * m) + (e - b) * (g * n - k * l) + (c - f) * (g * m - h * l) +
//                                   (g - l) * (b * f - c * e) + (m - h) * (a * f - c * d) + (k - n) * (a * e - b * d));
//          if (Math.Abs(ddd) > diff) {
//              diff = ddd;
//              Console.WriteLine(diff);
//          }
//          return (a - d)*(h*n - k*m) + (e - b)*(g*n - k*l) + (c - f)*(g*m - h*l) +
//                 (g - l)*(b*f - c*e) + (m - h)*(a*f - c*d) + (k - n)*(a*e - b*d) > ApproximateComparer.Tolerance;
//      }

      /// <summary>
        /// Testing that d in inside of the circumcircle of (a,b,c). 
        /// The good explanation of this test is in 
        /// "Guibas, Stolfi,"Primitives for the Manipulation of General Subdivisions and the Computation of Voronoi Diagrams
        /// 
        /// </summary>
        /// <param name="d"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public static bool InCircle(CdtSite d, CdtSite a, CdtSite b, CdtSite c) {
            Debug.Assert(Point.GetTriangleOrientationWithNoEpsilon(a.Point, b.Point, c.Point) == TriangleOrientation.Counterclockwise);
            /*
             *  | ax-dx ay-dy (ax-dx)^2+(ay-dy)^2|
             *  | bx-dx by-dy (bx-dx)^2+(by-dy)^2|
             *  | cx-dx cy-dy (cx-dx)^2+(cy-dy)^2|
             */
            var axdx = a.Point.X - d.Point.X;
            var aydy = a.Point.Y - d.Point.Y;
            var bxdx = b.Point.X - d.Point.X;
            var bydy = b.Point.Y - d.Point.Y;
            var cxdx = c.Point.X - d.Point.X;
            var cydy = c.Point.Y - d.Point.Y;
            var t0 = axdx * axdx + aydy * aydy;
            var t1 = bxdx * bxdx + bydy * bydy;
            var t2 = cxdx * cxdx + cydy * cydy;
            return axdx * (bydy * t2 - cydy * t1) - bxdx * (aydy * t2 - cydy * t0) + cxdx * (aydy * t1 - bydy * t0) > ApproximateComparer.Tolerance;                    
        }
 static bool IsIllegal(CdtSite pi, CdtSite a, CdtSite b, CdtSite c) {
     return InCone(pi, a, b, c) && InCircle(pi, a, b, c);
 }
예제 #38
0
        //        /// <summary>
        //        /// returns CdtEdges crossed by the segment a.Point, b.Point
        //        /// </summary>
        //        /// <param name="prevA">if prevA is not a null, that means the path is passing through prevA and might need to include
        //        /// the edge containing a.Point if such exists</param>
        //        /// <param name="a"></param>
        //        /// <param name="b"></param>
        //        /// <returns></returns>
        //        internal IEnumerable<CdtEdge> GetCdtEdgesCrossedBySegment(PolylinePoint prevA, PolylinePoint a, PolylinePoint b) {
        //            count++;
        //            if (dd) {
        //                var l = new List<DebugCurve> {
        //                                                 new DebugCurve("red", new Ellipse(5, 5, a.Point)),
        //                                                 new DebugCurve("blue", new Ellipse(5, 5, b.Point)),
        //                                                 new DebugCurve("blue", new LineSegment(a.Point, b.Point))
        //                                             };
        //
        //                l.AddRange(
        //                    GetTriangles().Select(
        //                        tr => new DebugCurve(100, 1, "green", new Polyline(tr.Sites.Select(v => v.Point)) {Closed = true})));
        //                LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
        //
        //            }
        //            var ret = new List<CdtEdge>();
        //            CdtEdge piercedEdge;
        //            CdtTriangle t = GetFirstTriangleAndPiercedEdge(a, b, out piercedEdge);
        //            if (ProperCrossing(a, b, piercedEdge))
        //                ret.Add(piercedEdge);
        //
        //            ret.AddRange(ContinueThreadingThroughTriangles(a,b,t, piercedEdge));
        //
        //            return ret;
        //        }

        /*
                static bool ProperCrossing(Point a, Point b, CdtEdge cdtEdge) {
                    return cdtEdge != null && cdtEdge.upperSite.Owner != cdtEdge.lowerSite.Owner &&
                           CrossEdgeInterior(cdtEdge, a, b);
                }
        */
        //        static int count;
        //        static bool db { get { return count == 125; }}

        internal IEnumerable<CdtEdge> ThreadEdgeThroughTriangles(CdtSite startSite, Point end) {
            CdtEdge piercedEdge;
            var triangle = FindFirstPiercedTriangle(startSite, end, out piercedEdge);
            if (triangle == null)
                yield break;

            var start = startSite.Point;
            foreach (var cdtEdge in ThreadThroughTriangles(start, end, triangle, piercedEdge))
                yield return cdtEdge;
        }
예제 #39
0
        CdtTriangle FindFirstPiercedTriangle(CdtSite startSite, Point target, out CdtEdge piercedEdge) {
            if (startSite != null) {
                foreach (var t in startSite.Triangles) {
                    piercedEdge = GetPiercedEdgeInSiteTriangle(t, startSite, target);
                    if (piercedEdge != null)
                        if (!PointIsInsideOfTriangle(target, t))
                            return t;
                }
            }

            piercedEdge = null;
            return null;
        }
        void LegalizeEdgeForOtherCwTriangle(CdtSite pi, CdtEdge edge) {
            var i=edge.CwTriangle.Edges.Index(edge);
//            if (i == -1)
//            {
//                List<DebugCurve> ls = new List<DebugCurve>();
//                ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point)));
//                for (int j = 0; j < 3; j++)
//                {
//                    var ee = edge.CwTriangle.Edges[j];
//                    ls.Add(new DebugCurve(100,1, j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point)));
//                }
//                ls.Add(new DebugCurve("purple", new LineSegment(edge.upperSite.Point, edge.lowerSite.Point)));
//                
//                LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
//            }
            Debug.Assert(i>=0);
            if (IsIllegal(pi, edge.upperSite, edge.CwTriangle.Sites[i + 2], edge.lowerSite)) {
                //ShowIllegalEdge(edge, i, pi);

                CdtEdge e = Flip(pi, edge);
                LegalizeEdge(pi, e.CwTriangle.OppositeEdge(pi) );
                LegalizeEdge(pi, e.CcwTriangle.OppositeEdge(pi));
            }
        }
예제 #41
0
 /// <summary>
 /// compare first y then -x coordinates
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns>1 if a is above b, 0 if points are the same and -1 if a is below b</returns>
 static internal int Above(CdtSite a, CdtSite b) {
     var del = a.Point.Y - b.Point.Y;
     if (del > 0)
         return 1;
     if (del < 0)
         return -1;
     del = a.Point.X - b.Point.X;
     return del > 0 ? -1 : (del < 0 ? 1 : 0); //for a horizontal edge the point with the smaller X is the upper point
 }
예제 #42
0
        void CheckSite(Point end, Set <Polyline> obstaclesToIgnore, HashSet <CdtSite> checkedSites, CdtSite s, double upperBound, Dictionary <Polyline, double> obstacles)
        {
            if (!checkedSites.Add(s))
            {
                return;
            }

            var poly = (Polyline)s.Owner;

            if (obstaclesToIgnore.Contains(poly))
            {
                return;
            }

            //distance to the obstacle
            PolylinePoint pp = FindPolylinePoint(poly, s.Point);
            double        par;
            double        d12  = Point.DistToLineSegment(end, pp.Point, pp.NextOnPolyline.Point, out par);
            double        d22  = Point.DistToLineSegment(end, pp.Point, pp.PrevOnPolyline.Point, out par);
            double        dist = Math.Min(d12, d22);

            if (dist > upperBound)
            {
                return;
            }

            double currentValue;

            if (!obstacles.TryGetValue(poly, out currentValue))
            {
                obstacles.Add(poly, dist);
            }
            else if (currentValue > dist)
            {
                obstacles[poly] = dist;
            }
        }
예제 #43
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
 static CdtEdge CreateEdgeOnOrderedCouple(CdtSite upperPoint, CdtSite lowerPoint)
 {
     Debug.Assert(Above(upperPoint.Point, lowerPoint.Point) == 1);
     return(new CdtEdge(upperPoint, lowerPoint));
 }
예제 #44
0
 static bool LocalInCircle(CdtSite v, CdtSite a, CdtSite b, CdtSite c, bool reverseTrangleWhenCompare)
 {
     return(reverseTrangleWhenCompare ? CdtSweeper.InCircle(v, a, c, b) : CdtSweeper.InCircle(v, a, b, c));
 }
        static CdtEdge Flip(CdtSite pi, CdtEdge edge) {
            Debug.Assert(!edge.IsAdjacent(pi));
            Debug.Assert(edge.CcwTriangle.Contains(pi) || edge.CwTriangle.Contains(pi));
            //get surrounding data
            CdtTriangle t, ot;
            if (edge.CcwTriangle.Contains(pi)) {
                t = edge.CcwTriangle;
                ot = edge.CwTriangle;
            } else {
                t = edge.CwTriangle;
                ot = edge.CcwTriangle;
            }
            Debug.Assert(t.Contains(pi));
            var eIndex = t.Edges.Index(edge);
            var eOtherIndex = ot.Edges.Index(edge);
            Debug.Assert(eIndex > -1 && eOtherIndex > -1);
            var pl = ot.Sites[eOtherIndex + 2];
            var edgeBeforPi = t.Edges[eIndex + 1];
            var edgeBeforPl = ot.Edges[eOtherIndex + 1];

            //changing t 
            var newEdge = Cdt.GetOrCreateEdge(pi, pl);
            t.Sites[eIndex + 1] = pl;
            t.Edges[eIndex] = edgeBeforPl;
            t.Edges[eIndex + 1] = newEdge;
            //changing ot
            ot.Sites[eOtherIndex + 1] = pi;
            ot.Edges[eOtherIndex] = edgeBeforPi;
            ot.Edges[eOtherIndex + 1] = newEdge;
            //orient the new edge and the two edges that move from one triangle to another
            if (edgeBeforPl.lowerSite == pl)
                edgeBeforPl.CcwTriangle = t;
            else
                edgeBeforPl.CwTriangle = t;

            if (edgeBeforPi.lowerSite == pi)
                edgeBeforPi.CcwTriangle = ot;
            else
                edgeBeforPi.CwTriangle = ot;

            if (newEdge.upperSite == pi) {
                newEdge.CcwTriangle = ot;
                newEdge.CwTriangle = t;
            } else {
                newEdge.CcwTriangle = t;
                newEdge.CwTriangle = ot;
            }
            Debug.Assert(CheckTriangle(t));
            Debug.Assert(CheckTriangle(t));
            //ShowFlip(pi, t, ot);
            edge.upperSite.Edges.Remove(edge); //forget the edge 
            return newEdge;
        }
예제 #46
0
 CdtEdge GetPiercedEdgeInSiteTriangle(CdtTriangle t, CdtSite site, Point target) {
     var e = t.OppositeEdge(site);
     return PiercedEdgeQuery(e, site.Point, target, t);
 }
      /// <summary>
        /// 
        /// </summary>
        /// <param name="pi"></param>
        /// <param name="a">point on left side of the cone</param>
        /// <param name="b">the apex</param>
        /// <param name="c">point on the right side of the cone</param>
        static bool InCone(CdtSite pi, CdtSite a, CdtSite b, CdtSite c) {
            Debug.Assert(Point.GetTriangleOrientationWithNoEpsilon(a.Point,b.Point,c.Point)==TriangleOrientation.Counterclockwise);

            return Point.GetTriangleOrientationWithNoEpsilon(a.Point, pi.Point, b.Point) == TriangleOrientation.Clockwise &&
                Point.GetTriangleOrientationWithNoEpsilon(b.Point, pi.Point, c.Point) == TriangleOrientation.Clockwise;
        }
 void ProjectToFront(CdtSite site, out RBNode<CdtFrontElement> frontElement) {
     frontElement = front.FindLast(s => s.X <= site.Point.X);
 }
 /// <summary>
 /// in the trianlge, which is always oriented counterclockwise, the edge starts at site 
 /// </summary>
 /// <param name="site"></param>
 /// <param name="edge"></param>
 void BindEdgeToTriangle(CdtSite site, CdtEdge edge) {
     if (site == edge.upperSite)
         edge.CcwTriangle = this;
     else
         edge.CwTriangle = this;
 }
예제 #50
0
        void AddP1AndP2() {
            var box = Rectangle.CreateAnEmptyBox();
            foreach (var site in PointsToSites.Keys)
                box.Add(site);

            var delx = box.Width / 3;
            var dely = box.Height / 3;
            P1 = new CdtSite(box.LeftBottom + new Point(-delx, -dely));
            P2 = new CdtSite(box.RightBottom + new Point(delx, -dely));
        }
 internal bool Contains(CdtSite cdtSite)
 {
     return(Sites.Contains(cdtSite));
 }
 static void ShowFlip(CdtSite pi, CdtTriangle t, CdtTriangle ot) {
     List<DebugCurve> ls=new List<DebugCurve>();
     ls.Add(new DebugCurve(new Ellipse(2,2, pi.Point)));
     for(int i=0;i<3;i++) {
         var e=t.Edges[i];
         ls.Add(new DebugCurve(100, 1, "red", new LineSegment(e.upperSite.Point,e.lowerSite.Point)));
     }
     for (int i = 0; i < 3; i++)
     {
         var e = ot.Edges[i];
         ls.Add(new DebugCurve(100, 1, "blue", new LineSegment(e.upperSite.Point, e.lowerSite.Point)));
     }
     ls.Add(new DebugCurve(Circumcircle(t.Sites[0].Point, t.Sites[1].Point, t.Sites[2].Point)));
     LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
 }
 void AddSiteToRightPolygon(CdtSite site)
 {
     AddSiteToPolygonWithCheck(site, rightPolygon);
 }
 void LegalizeEdgeForOtherCcwTriangle(CdtSite pi, CdtEdge edge) {
     var i = edge.CcwTriangle.Edges.Index(edge);
     if (IsIllegal(pi, edge.lowerSite, edge.CcwTriangle.Sites[i + 2], edge.upperSite)) {
         CdtEdge e = Flip(pi, edge);                
         LegalizeEdge(pi, e.CwTriangle.OppositeEdge(pi));
         LegalizeEdge(pi, e.CcwTriangle.OppositeEdge(pi));
     }
 }
예제 #55
0
 static internal CdtEdge GetOrCreateEdge(CdtSite a, CdtSite b) {
     if (Above(a.Point, b.Point) == 1) {
         var e = a.EdgeBetweenUpperSiteAndLowerSite(b);
         if (e != null)
             return e;
         return CreateEdgeOnOrderedCouple(a, b);
     }
     else {
         var e = b.EdgeBetweenUpperSiteAndLowerSite(a);
         if (e != null)
             return e;
         return CreateEdgeOnOrderedCouple(b, a);
     }
 }
예제 #56
0
 static CdtEdge CreateEdgeOnOrderedCouple(CdtSite upperPoint, CdtSite lowerPoint) {
     Debug.Assert(Above(upperPoint.Point, lowerPoint.Point) == 1);
     return new CdtEdge(upperPoint, lowerPoint);
 }
예제 #57
0
파일: Cdt.cs 프로젝트: suprcodr/EFDesigner
 static int OnComparison(CdtSite a, CdtSite b)
 {
     return(Above(a.Point, b.Point));
 }
예제 #58
0
 static int OnComparison(CdtSite a, CdtSite b) {
     return Above(a.Point, b.Point);
 }
예제 #59
0
        void TriangulatePolygon(int start, int end, List <CdtSite> polygon, CdtSite a, CdtSite b, bool reverseTrangleWhenCompare)
        {
//            if(CdtSweeper.db)
//               CdtSweeper.ShowFront(triangles,front, Enumerable.Range(start, end-start+1).Select(i=> new Ellipse(10,10,polygon[i].Point)).ToArray(), new[]{new LineSegment(a.Point,b.Point)});
            var c      = polygon[start];
            int cIndex = start;

            for (int i = start + 1; i <= end; i++)
            {
                var v = polygon[i];
                if (LocalInCircle(v, a, b, c, reverseTrangleWhenCompare))
                {
                    cIndex = i;
                    c      = v;
                }
            }
            var t = new CdtTriangle(a, b, c, createEdgeDelegate);

            triangles.Insert(t);
            addedTriangles.Add(t);
            if (start < cIndex)
            {
                TriangulatePolygon(start, cIndex - 1, polygon, a, c, reverseTrangleWhenCompare);
            }
            if (cIndex < end)
            {
                TriangulatePolygon(cIndex + 1, end, polygon, c, b, reverseTrangleWhenCompare);
            }
        }
 List<DebugCurve> ShowIllegalEdge(CdtEdge edge, CdtSite pi, int i) {
     List<DebugCurve> ls = new List<DebugCurve>();
     ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point)));
     for (int j = 0; j < 3; j++) {
         var ee = edge.CcwTriangle.Edges[j];
         ls.Add(new DebugCurve(j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point)));
     }
     ls.Add(new DebugCurve(100,1, "black", Circumcircle(edge.CcwTriangle.Sites[0].Point,edge.CcwTriangle.Sites[1].Point,edge.CcwTriangle.Sites[2].Point)));
     LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls);
     return ls;
 }