Exemple #1
0
        private void FillRemovedConnectedRegion(CdtTriangle t, Set <CdtTriangle> removedTriangles)
        {
            if (removedTriangles.Contains(t))
            {
                return;
            }
            var q = new Queue <CdtTriangle>();

            q.Enqueue(t);
            while (q.Count > 0)
            {
                t = q.Dequeue();
                removedTriangles.Insert(t);
                foreach (var e in t.Edges)
                {
                    if (!e.Constrained)
                    {
                        var tr = e.GetOtherTriangle(t);
                        if (tr != null && !removedTriangles.Contains(tr))
                        {
                            q.Enqueue(tr);
                        }
                    }
                }
            }
        }
Exemple #2
0
        public void CdtTriangleCreationTest()
        {
            var a   = new CdtSite(new Point());
            var b   = new CdtSite(new Point(2, 0));
            var c   = new CdtSite(new Point(1, 2));
            var tri = new CdtTriangle(a, b, c, Cdt.GetOrCreateEdge);
            var e   = tri.Edges[0];

            Assert.IsTrue(e.upperSite == a);
            Assert.IsTrue(e.lowerSite == b);
            Assert.IsTrue(e.CcwTriangle == tri && e.CwTriangle == null);

            e = tri.Edges[1];
            Assert.IsTrue(e.upperSite == c);
            Assert.IsTrue(e.lowerSite == b);
            Assert.IsTrue(e.CwTriangle == tri && e.CcwTriangle == null);

            e = tri.Edges[2];
            Assert.IsTrue(e.upperSite == c);
            Assert.IsTrue(e.lowerSite == a);
            Assert.IsTrue(e.CcwTriangle == tri && e.CwTriangle == null);

            var tri0 = new CdtTriangle(new CdtSite(new Point(2, 2)), tri.Edges[1], Cdt.GetOrCreateEdge);

            Assert.IsTrue(tri0.Edges[0] == tri.Edges[1]);
            Assert.IsTrue(tri.Edges[1].CcwTriangle != null && tri.Edges[1].CwTriangle != null);
        }
 internal CdtThreader(CdtTriangle startTriangle, Point start, Point end)
 {
     Debug.Assert(PointLocationForTriangle(start, startTriangle) != PointLocation.Outside);
     currentTriangle = startTriangle;
     this.start      = start;
     this.end        = end;
 }
Exemple #4
0
        /// <summary>
        /// checks if an edge intersects obstacles
        /// otherwise it calulates distances to the closest obstacles
        /// </summary>
        internal bool EdgeIsLegal(Station v, Station u, Point vPosition, Point uPosition, Set <Polyline> obstaclesToIgnore)
        {
            var start = v.Position;

            CdtTriangle currentTriangle = v.CdtTriangle;

            Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle));

            Point end = u.Position;

            if (Cdt.PointIsInsideOfTriangle(end, currentTriangle))
            {
                return(true);
            }

            var threader = new CdtThreader(currentTriangle, start, end);

            while (threader.MoveNext())
            {
                var piercedEdge = threader.CurrentPiercedEdge;
                if (piercedEdge.Constrained)
                {
                    Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner);
                    var poly = (Polyline)piercedEdge.lowerSite.Owner;
                    if (!obstaclesToIgnore.Contains(poly))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemple #5
0
        Dictionary <Polyline, double> FindCloseObstaclesForHub(CdtTriangle startTriangle, Point start, Point end, Set <Polyline> obstaclesToIgnore, double upperBound)
        {
            var obstacles = new Dictionary <Polyline, double>();
            List <CdtTriangle> nearestTriangles;

            if (!ThreadLineSegmentThroughTriangles(startTriangle, start, end, obstaclesToIgnore, out nearestTriangles))
            {
                return(null);
            }

            var checkedSites = new HashSet <CdtSite>();

            foreach (var t in nearestTriangles)
            {
                foreach (var s in t.Sites)
                {
                    CheckSite(end, obstaclesToIgnore, checkedSites, s, upperBound, obstacles);

                    var edge = t.OppositeEdge(s);
                    var ot   = edge.GetOtherTriangle(t);
                    if (ot != null)
                    {
                        CheckSite(end, obstaclesToIgnore, checkedSites, ot.OppositeSite(edge), upperBound, obstacles);
                    }
                }
            }

            return(obstacles);
        }
Exemple #6
0
        private static void ThreadOnTriangle(Point start, Point end, CdtTriangle t)
        {
            var threader = new CdtThreader(t, start, end);

            while (threader.MoveNext())
            {
            }
        }
        private bool GetCenterOfDescribedCircle(CdtTriangle triangle, out Point x)
        {
            var p0 = (triangle.Sites[0].Point + triangle.Sites[1].Point) / 2;
            var p1 = p0 + (triangle.Sites[0].Point - triangle.Sites[1].Point).Rotate(-Math.PI / 2);
            var p2 = (triangle.Sites[1].Point + triangle.Sites[2].Point) / 2;
            var p3 = p0 + (triangle.Sites[1].Point - triangle.Sites[2].Point).Rotate(-Math.PI / 2);

            return(Point.LineLineIntersection(p0, p1, p2, p3, out x));
        }
Exemple #8
0
        static bool SeparatedByEdge(CdtTriangle triangle, int i, CdtSite site)
        {
            var e  = triangle.Edges[i];
            var s  = triangle.Sites[i + 2];
            var a0 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(s.Point, e.upperSite.Point, e.lowerSite.Point));
            var a1 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(site.Point, e.upperSite.Point, e.lowerSite.Point));

            return(a0 * a1 <= 0);
        }
Exemple #9
0
 static void AddTriangleToListOfDebugCurves(List <DebugCurve> debugCurves, CdtTriangle triangle, byte transparency,
                                            double width, string color)
 {
     foreach (CdtEdge cdtEdge in triangle.Edges)
     {
         debugCurves.Add(new DebugCurve(transparency, width, color,
                                        new LineSegment(cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point)));
     }
 }
Exemple #10
0
        /// <summary>
        /// returns false iff the edge overlap an obstacle
        /// </summary>
        bool ThreadLineSegmentThroughTriangles(CdtTriangle currentTriangle, Point start, Point end, Set <Polyline> obstaclesToIgnore,
                                               out List <CdtTriangle> triangles)
        {
            Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle));
            triangles = new List <CdtTriangle>();

            if (Cdt.PointIsInsideOfTriangle(end, currentTriangle))
            {
                triangles.Add(currentTriangle);
                return(true);
            }

            var threader = new CdtThreader(currentTriangle, start, end);

            triangles.Add(currentTriangle);

            while (threader.MoveNext())
            {
                triangles.Add(threader.CurrentTriangle);
                var piercedEdge = threader.CurrentPiercedEdge;
                if (piercedEdge.Constrained)
                {
                    Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner);
                    var poly = (Polyline)piercedEdge.lowerSite.Owner;
                    if (!obstaclesToIgnore.Contains(poly))
                    {
                        return(false);
                    }
                }
            }
            if (threader.CurrentTriangle != null)
            {
                triangles.Add(threader.CurrentTriangle);
            }
//
//            int positiveSign, negativeSign;
//            CdtEdge piercedEdge = FindFirstPiercedEdge(currentTriangle, start, end, out negativeSign, out positiveSign,  null);
//
//            Debug.Assert(positiveSign > negativeSign);
//
//            Debug.Assert(piercedEdge != null);
//
//            do {
//                triangles.Add(currentTriangle);
//                if (piercedEdge.Constrained) {
//                    Debug.Assert(piercedEdge.lowerSite.Owner == piercedEdge.upperSite.Owner);
//                    Polyline poly = (Polyline)piercedEdge.lowerSite.Owner;
//                    if (!obstaclesToIgnore.Contains(poly)) return false;
//                }
//            }
//            while (FindNextPierced(start, end, ref currentTriangle, ref piercedEdge, ref negativeSign, ref positiveSign));
//            if (currentTriangle != null)
//                triangles.Add(currentTriangle);

            return(true);
        }
Exemple #11
0
 static bool SeparatedByConstrainedEdge(CdtTriangle triangle, CdtSite site)
 {
     for (int i = 0; i < 3; i++)
     {
         if (SeparatedByEdge(triangle, i, site))
         {
             return(true);
         }
     }
     return(false);
 }
        void TryToAssigenTriangleToVertex(CdtTriangle triangle, SdVertex vertex)
        {
            if (vertex.Triangle != null)
            {
                return;
            }

            if (Cdt.PointIsInsideOfTriangle(vertex.Point, triangle))
            {
                vertex.Triangle = triangle;
            }
        }
        static bool PointBelongsToInteriorOfTriangle(Point point, CdtTriangle cdtTriangle)
        {
            for (int i = 0; i < 3; i++)
            {
                if (Point.GetTriangleOrientation(cdtTriangle.Sites[i].Point, cdtTriangle.Sites[i + 1].Point,
                                                 point) != TriangleOrientation.Counterclockwise)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #14
0
        static List <DebugCurve> ThreadOnTriangle(Point start, Point end, CdtTriangle t)
        {
            var l = new List <DebugCurve> {
                new DebugCurve(10, "red", new LineSegment(start, end))
            };

            AddTriangleToListOfDebugCurves(l, t, 100, 3, "brown");
            var threader = new CdtThreader(t, start, end);

            foreach (var triangle in threader.Triangles())
            {
                AddTriangleToListOfDebugCurves(l, triangle, 100, 3, "black");
                //                CdtSweeper.ShowFront(trs, null, new ICurve[] { new LineSegment(start, end), new Polyline(triangle.Sites.Select(s => s.Point)) { Closed = true } }, new []{new LineSegment(threader.CurrentPiercedEdge.lowerSite.Point,threader.CurrentPiercedEdge.upperSite.Point) });
            }
            return(l);
        }
 void StepFromTriangleInteriorPoint(CdtTriangle triangle)
 {
     if (PointBelongsToInteriorOfTriangle(segEnd.Point, triangle))
     {
         lastCrossedFeature = triangle;
         return;
     }
     //we cross an edge
     for (int i = 0; i < 3; i++)
     {
         if (PointIsInsideCone(segEnd.Point, segStart.Point, triangle.Sites[i + 1].Point,
                               triangle.Sites[i].Point))
         {
             CrossTriangleEdge(triangle.Edges[i]);
             return;
         }
     }
 }
        internal static PointLocation PointLocationForTriangle(Point p, CdtTriangle triangle)
        {
            bool seenBoundary = false;

            for (int i = 0; i < 3; i++)
            {
                var area = Point.SignedDoubledTriangleArea(p, triangle.Sites[i].Point, triangle.Sites[i + 1].Point);
                if (area < -ApproximateComparer.DistanceEpsilon)
                {
                    return(PointLocation.Outside);
                }
                if (area < ApproximateComparer.DistanceEpsilon)
                {
                    seenBoundary = true;
                }
            }

            return(seenBoundary ? PointLocation.Boundary : PointLocation.Inside);
        }
Exemple #17
0
        void TestTriangle(CdtTriangle triangle, Set <CdtSite> usedSites)
        {
            var tsites = triangle.Sites;

            foreach (var site in usedSites)
            {
                if (!tsites.Contains(site))
                {
                    Assert.IsTrue(SeparatedByConstrainedEdge(triangle, site) || !CdtSweeper.InCircle(site, tsites[0], tsites[1], tsites[2]));
//                    {
//                        List<ICurve> redCurves = new List<ICurve>();
//                        redCurves.Add(new Ellipse(2, 2, site.Point));
//                        List<ICurve> blueCurves = new List<ICurve>();
//                        blueCurves.Add(Circumcircle(tsites[0].Point, tsites[1].Point, tsites[2].Point));
//                        ShowFront(Triangles, front, redCurves, blueCurves);
//                    }
                }
            }
        }
        static object TryCreateFeatureWhichIsNotSite(PolylinePoint pp, CdtTriangle triangle)
        {
            Debug.Assert(!triangle.Sites.Any(s => ApproximateComparer.Close(pp.Point, s.Point)));
            var a0 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[0].Point, triangle.Sites[1].Point);

            if (a0 == TriangleOrientation.Clockwise)
            {
                return(null);
            }

            var a1 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[1].Point, triangle.Sites[2].Point);

            if (a1 == TriangleOrientation.Clockwise)
            {
                return(null);
            }

            var a2 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[2].Point, triangle.Sites[3].Point);

            if (a2 == TriangleOrientation.Clockwise)
            {
                return(null);
            }

            if (a0 == TriangleOrientation.Counterclockwise &&
                a1 == TriangleOrientation.Counterclockwise &&
                a2 == TriangleOrientation.Counterclockwise)
            {
                return(triangle);
            }

            if (a0 == TriangleOrientation.Collinear)
            {
                return(triangle.Edges[0]);
            }
            if (a1 == TriangleOrientation.Collinear)
            {
                return(triangle.Edges[1]);
            }
            Debug.Assert(a2 == TriangleOrientation.Collinear);
            return(triangle.Edges[2]);
        }
        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;
                    }
                }
            }
        }
        void AddVoronoiCite(CdtTriangle triangle)
        {
            Point p;
            var   goodTriangle = GetCenterOfDescribedCircle(triangle, out p);

            if (!goodTriangle)
            {
                return;
            }
            if (!BoundingBox.Contains(p))
            {
                return;
            }
            var rect = new Rectangle(p);

            rect.Pad(eps);
            if (voronoiSiteTree.GetAllIntersecting(rect).Count() > 0)
            {
                return;
            }

            voronoiSiteTree.Add(rect, p);
        }
Exemple #21
0
        private void AddTriangleToCanvas(CdtTriangle t)
        {
            var color = new System.Windows.Media.Color();

            color.A = 100;
            color.B = 255;
            var wpfTriangle = new Polygon {
                Stroke             = new SolidColorBrush(color),
                StrokeEndLineCap   = PenLineCap.Round,
                StrokeStartLineCap = PenLineCap.Round,
                StrokeLineJoin     = PenLineJoin.Round,
                StrokeThickness    = scroller.GetScale()
            };



            PointCollection trianglePoints = new PointCollection();

            trianglePoints.Add(ToWpfPoint(t.Sites[0].Point));
            trianglePoints.Add(ToWpfPoint(t.Sites[1].Point));
            trianglePoints.Add(ToWpfPoint(t.Sites[2].Point));
            wpfTriangle.Points = trianglePoints;
            diagram.Canvas.Children.Add(wpfTriangle);
        }
Exemple #22
0
        /// <summary>
        /// returns null iff the edge overlap an obstacle
        /// </summary>
        Dictionary <Polyline, Tuple <Point, Point> > FindCloseObstaclesForBundle(CdtTriangle startTriangle, Point start,
                                                                                 Point end, Set <Polyline> obstaclesToIgnore,
                                                                                 double upperBound)
        {
            var obstacles = new Dictionary <Polyline, Tuple <Point, Point> >();
            List <CdtTriangle> list;

            if (!ThreadLineSegmentThroughTriangles(startTriangle, start, end, obstaclesToIgnore, out list))
            {
                return(null);
            }

            if (!ComputeForcesForBundles && !bundlingSettings.HighestQuality)
            {
                return(obstacles);
            }

            var checkedSites = new HashSet <CdtSite>();

            foreach (var t in list)
            {
                foreach (var s in t.Sites)
                {
                    if (!checkedSites.Add(s))
                    {
                        continue;
                    }

                    var poly = (Polyline)s.Owner;
                    if (obstaclesToIgnore.Contains(poly))
                    {
                        continue;
                    }

                    PolylinePoint pp = FindPolylinePoint(poly, s.Point);
                    double        par11, par12, par21, par22;
                    double        d12 = Point.MinDistBetweenLineSegments(pp.Point, pp.NextOnPolyline.Point, start, end,
                                                                         out par11, out par12);
                    double d22 = Point.MinDistBetweenLineSegments(pp.Point, pp.PrevOnPolyline.Point, start, end,
                                                                  out par21, out par22);
                    Point  r1, r2;
                    double dist;
                    if (d12 < d22)
                    {
                        dist = d12;
                        if (dist > upperBound)
                        {
                            continue;
                        }
                        r1 = pp.Point + (pp.NextOnPolyline.Point - pp.Point) * par11;
                        r2 = start + (end - start) * par12;
                    }
                    else
                    {
                        dist = d22;
                        if (dist > upperBound)
                        {
                            continue;
                        }
                        r1 = pp.Point + (pp.PrevOnPolyline.Point - pp.Point) * par21;
                        r2 = start + (end - start) * par22;
                    }
                    //if (dist > upperBound) continue;

                    Tuple <Point, Point> currentValue;
                    if (!obstacles.TryGetValue(poly, out currentValue))
                    {
                        obstacles.Add(poly, new Tuple <Point, Point>(r1, r2));
                    }
                }
            }

            return(obstacles);
        }
Exemple #23
0
 ///<summary>
 ///</summary>
 ///<param name="triangle"></param>
 ///<returns></returns>
 public CdtTriangle GetOtherTriangle(CdtTriangle triangle)
 {
     return(ccwTriangle == triangle ? cwTriangle : ccwTriangle);
 }
        internal void FindNextPierced()
        {
            Debug.Assert(negativeSign < positiveSign);

            /*List<DebugCurve> l = null;
             * if (db) {
             *  l = new List<DebugCurve>();
             *  l.Add(new DebugCurve(0.05, "red", new LineSegment(start, end)));
             *  l.Add(new DebugCurve(0.05, "blue", new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point)));
             *  l.Add(new DebugCurve(new Ellipse(3, 3, end)));
             *
             *  var ii = currentTriangle.Edges.Index(piercedEdge);
             *  for (int j = ii + 1; j <= ii + 2; j++)
             *      l.Add(new DebugCurve(0.05, "brown", new LineSegment(currentTriangle.Edges[j].upperSite.Point, currentTriangle.Edges[j].lowerSite.Point)));
             * }*/
            currentTriangle = currentPiercedEdge.GetOtherTriangle(currentTriangle);
//            ShowDebug(null,currentPiercedEdge,currentTriangle);

            /* if (db) {
             *   for (int j = 0; j <= 2; j++) {
             *       var piercedEdge = currentTriangle.Edges[j];
             *       if (piercedEdge == piercedEdge) continue;
             *       l.Add(new DebugCurve(0.05, new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point)));
             *   }
             *
             *   LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l.ToArray());
             * }*/
            if (currentTriangle == null)
            {
                currentPiercedEdge = null;
                return;
            }
            var i = currentTriangle.Edges.Index(currentPiercedEdge);
            int j; //pierced index
            var oppositeSite     = currentTriangle.Sites[i + 2];
            var oppositeSiteSign = GetHyperplaneSign(oppositeSite);

            if (negativeSign == 0)
            {
                Debug.Assert(positiveSign == 1);
                if (oppositeSiteSign == -1 || oppositeSiteSign == 0)
                {
                    negativeSign = oppositeSiteSign;
                    j            = i + 1;
                }
                else
                {
                    j = i + 2;
                }
            }
            else if (positiveSign == 0)
            {
                Debug.Assert(negativeSign == -1);
                if (oppositeSiteSign == 1 || oppositeSiteSign == 0)
                {
                    positiveSign = oppositeSiteSign;
                    j            = i + 2;
                }
                else
                {
                    j = i + 1;
                }
            }
            else if (oppositeSiteSign != positiveSign)
            {
                negativeSign = oppositeSiteSign;
                j            = i + 1;
            }
            else
            {
                Debug.Assert(negativeSign != oppositeSiteSign);
                positiveSign = oppositeSiteSign;
                j            = i + 2;
            }

            currentPiercedEdge =
                Point.SignedDoubledTriangleArea(end, currentTriangle.Sites[j].Point, currentTriangle.Sites[j + 1].Point) <
                -ApproximateComparer.DistanceEpsilon
                    ? currentTriangle.Edges[j]
                    : null;

//            ShowDebug(null,currentPiercedEdge, currentTriangle);
        }
 static internal HitTestBehavior Test(Point pnt, CdtTriangle t)
 {
     return(Cdt.PointIsInsideOfTriangle(pnt, t) ? HitTestBehavior.Stop : HitTestBehavior.Continue);
 }