示例#1
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);
        }
        /// <summary>
        ///
        /// </summary>
        public static void Test()
        {
#if DEBUG && !SHARPKIT
            int count  = 100;
            var random = new Random(3);
            var points = new List <Point>();
            for (int i = 0; i < count; i++)
            {
                points.Add(20 * new Point(random.NextDouble(), random.NextDouble()));
            }

            var cdt = new Cdt(points, null, null);
            cdt.Run();
            var ret = GetMstOnCdt(cdt, e => (e.lowerSite.Point - e.upperSite.Point).Length);
            var l   = new List <DebugCurve>();
            foreach (var s in cdt.PointsToSites.Values)
            {
                foreach (var e in s.Edges)
                {
                    l.Add(new DebugCurve(100, 0.1, "black", new LineSegment(e.lowerSite.Point, e.upperSite.Point)));
                }
            }
            foreach (var e in ret)
            {
                l.Add(new DebugCurve(100, 0.12, "red", new LineSegment(e.lowerSite.Point, e.upperSite.Point)));
            }
            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
#endif
        }
示例#3
0
        internal MetroGraphData(EdgeGeometry[] regularEdges,
                                RectangleNode <Polyline> looseTree, RectangleNode <Polyline> tightTree,
                                BundlingSettings bundlingSettings, Cdt cdt,
                                Dictionary <EdgeGeometry, Set <Polyline> > edgeLooseEnterable, Dictionary <EdgeGeometry, Set <Polyline> > edgeTightEnterable, Func <Port, Polyline> loosePolylineOfPort)
        {
            //Debug.Assert(cdt != null);
            this.regularEdges = regularEdges;
            if (cdt != null)
            {
                Cdt = cdt;
            }
            else
            {
                Cdt = BundleRouter.CreateConstrainedDelaunayTriangulation(looseTree);
            }

            EdgeLooseEnterable  = edgeLooseEnterable;
            EdgeTightEnterable  = edgeTightEnterable;
            LoosePolylineOfPort = loosePolylineOfPort;

            looseIntersections = new Intersections(this, bundlingSettings, looseTree, station => station.EnterableLoosePolylines);
            tightIntersections = new Intersections(this, bundlingSettings, tightTree, station => station.EnterableTightPolylines);
            cdtIntersections   = new CdtIntersections(this, bundlingSettings);

            Initialize(false);
        }
示例#4
0
        static Cdt GetConstrainedDelaunayTriangulation(IEnumerable <Polyline> obstacles)
        {
            var constrainedDelaunayTriangulation = new Cdt(null, obstacles, null);

            constrainedDelaunayTriangulation.Run();
            return(constrainedDelaunayTriangulation);
        }
 void RestoreCapacities()
 {
     if (Cdt != null)
     {
         Cdt.RestoreEdgeCapacities();
     }
 }
示例#6
0
        private CdtEdge FindEdge(PolylinePoint a, PolylinePoint b, Cdt cdt)
        {
            int aIsAboveB = Cdt.Above(a.Point, b.Point);

            System.Diagnostics.Debug.Assert(aIsAboveB != 0);
            if (aIsAboveB > 0)
            {
                foreach (var e in cdt.FindSite(a.Point).Edges)
                {
                    if (e.lowerSite.Point == b.Point)
                    {
                        return(e);
                    }
                }
            }
            else
            {
                foreach (var e in cdt.FindSite(b.Point).Edges)
                {
                    if (e.lowerSite.Point == a.Point)
                    {
                        return(e);
                    }
                }
            }

            throw new InvalidOperationException("cannot find an edge of a polyline in the tessellation");
        }
 public IntersectionCache(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, CostCalculator costCalculator, Cdt cdt)
 {
     Debug.Assert(cdt != null);
     this.metroGraphData   = metroGraphData;
     this.bundlingSettings = bundlingSettings;
     this.costCalculator   = costCalculator;
     this.cdt = cdt;
 }
示例#8
0
 private void CleanUpTriangles(Shape shape, ref Set <CdtTriangle> triangles, Cdt cdt)
 {
     CleanUpExternalTriangles(shape, ref triangles, cdt);
     foreach (var sh in shape.Children)
     {
         CleanUpInternalTriangles(sh, ref triangles, cdt);
     }
 }
示例#9
0
        public void SmallTriangulation()
        {
#if TEST_MSAGL && TEST_MSAGL
            GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions();
#endif
            var cdt = new Cdt(Points(), null, new [] { new SymmetricTuple <Point>(new Point(109, 202), new Point(506, 135)),
                                                       new SymmetricTuple <Point>(new Point(139, 96), new Point(452, 96)) }.ToList());
            cdt.Run();
        }
示例#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);
        }
示例#11
0
        private static void GetProximityRelations(GeometryGraph graphOriginal, out HashSet <Tuple <int, int> > proximityEdges, out HashSet <Tuple <int, int, int> > proximityTriangles)
        {
// triangulation needed for statistics
            Cdt cdt = new Cdt(graphOriginal.Nodes.Select((v, index) => new Tuple <Point, object>(
                                                             v.Center, (object)(index))));

            cdt.Run();
            proximityTriangles = GetProximityTriangles(cdt);
            proximityEdges     = GetProximityEdges(cdt);
        }
示例#12
0
        void Triangulate(int n, double size)
        {
            var random = new Random(n);
            var w      = n * size;
            var cdt    = new Cdt(PointsForCdt(random, n, w), null, SegmentsForCdt(w).ToList());

            cdt.Run();
#if TEST_MSAGL && TEST_MSAGL
            CdtSweeper.ShowFront(cdt.GetTriangles(), null, null, null);
#endif
        }
示例#13
0
        static void TestTriangulationOnPolys()
        {
            FileStream stream     = File.Open("polys", FileMode.Open);
            var        bformatter = new BinaryFormatter();

            var polys = (Polyline[])bformatter.Deserialize(stream);

            stream.Close();
            var cdt = new Cdt(null, polys, null);

            cdt.Run();
        }
        void TryToAssigenTriangleToVertex(CdtTriangle triangle, SdVertex vertex)
        {
            if (vertex.Triangle != null)
            {
                return;
            }

            if (Cdt.PointIsInsideOfTriangle(vertex.Point, triangle))
            {
                vertex.Triangle = triangle;
            }
        }
示例#15
0
        public void TestRepeatedSite()
        {
            //in this method the triangulation is such that a repeated site appears in EdgeEvent
            var stream     = File.Open("polys", FileMode.Open);
            var bformatter = new BinaryFormatter();

            var polys = (Polyline[])bformatter.Deserialize(stream);

            stream.Close();
            var cdt = new Cdt(null, polys, null);

            cdt.Run();
            TestTriangles(cdt.GetTriangles());
        }
        bool DoSingleIteration(int currentIteration, ref bool scanlinePhase)
        {
            List <Tuple <Point, object> > sites =
                nodePositions.Select((p, index) => new Tuple <Point, object>(p, index)).ToList();
            var triangulation = new Cdt(sites);

            triangulation.Run();

            List <Tuple <int, int, double, double> > proximityEdgesWithDistance;
            int numCrossings = GetProximityEdgesWithDistance(Graph, triangulation, nodeSizes,
                                                             out proximityEdgesWithDistance);

            if (scanlinePhase || numCrossings == 0)
            {
                scanlinePhase = true;
                numCrossings  = CompleteProximityGraphWithRTree(ref numCrossings, proximityEdgesWithDistance);
            }
#if DEBUG
            int realCrossings = CountCrossingsWithRTree(nodeSizes);
            crossingsOverTime.Add(realCrossings);
            if (currentIteration % 10 == 0)
            {
                Console.WriteLine("Scanline: {0}, Crossings: {1}", scanlinePhase, numCrossings);
            }
#endif

            if (numCrossings == 0)
            {
                return(true);
            }

            AddStressFromProximityEdges(StressSolver, proximityEdgesWithDistance);
            List <Point> newPositions = StressSolver.IterateAll();

            ShowCurrentMovementVectors(currentIteration, nodeSizes, nodePositions, newPositions,
                                       proximityEdgesWithDistance,
                                       null);

            UpdatePointsAndBoxes(newPositions);
            //clear the data structures
            StressSolver.ClearVotings();
#if DEBUG
            for (int i = 0; i < nodePositions.Length; i++)
            {
                trajectories[i].AddPoint(newPositions[i]);
            }
#endif
            return(false);
        }
示例#17
0
        private static HashSet <Tuple <int, int, int> > GetProximityTriangles(Cdt cdt)
        {
            HashSet <Tuple <int, int, int> > proxTriangles = new HashSet <Tuple <int, int, int> >();

            foreach (var triangle in cdt.GetTriangles())
            {
                int a = (int)triangle.Sites[0].Owner;
                int b = (int)triangle.Sites[1].Owner;
                int c = (int)triangle.Sites[2].Owner;

                proxTriangles.Add(Tuple.Create(a, b, c));
            }

            return(proxTriangles);
        }
示例#18
0
        static void Triangulation(bool reverseX)
        {
#if TEST_MSAGL
            DisplayGeometryGraph.SetShowFunctions();
#endif
            int r = reverseX ? -1 : 1;
            IEnumerable <Point> points = Points().Select(p => new Point(r * p.X, p.Y));

            var poly = (Polyline)RussiaPolyline.GetTestPolyline().ScaleFromOrigin(1, 1);
            var cdt  = new Cdt(null, new[] { poly }, null);
            cdt.Run();
#if TEST_MSAGL
            CdtSweeper.ShowFront(cdt.GetTriangles(), null, null, null);
#endif
        }
示例#19
0
 internal CdtEdge EdgeBetweenUpperSiteAndLowerSite(CdtSite b)
 {
     Debug.Assert(Cdt.Above(this, b) > 0);
     if (Edges != null)
     {
         foreach (var edge in Edges)
         {
             if (edge.lowerSite == b)
             {
                 return(edge);
             }
         }
     }
     return(null);
 }
        void SetVertexTriangles()
        {
            var triangleTree =
                RectangleNode <CdtTriangle> .CreateRectangleNodeOnEnumeration(
                    Cdt.GetTriangles().Select(t => new RectangleNode <CdtTriangle>(t, t.BoundingBox())));

            var vertexTree =
                RectangleNode <SdVertex> .CreateRectangleNodeOnEnumeration(
                    vertexArray.Select(v => new RectangleNode <SdVertex>(v, new Rectangle(v.Point))));

            RectangleNodeUtils.CrossRectangleNodes(triangleTree, vertexTree, TryToAssigenTriangleToVertex);
            foreach (var v in vertexArray)
            {
                Debug.Assert(v.Triangle != null);
            }
        }
示例#21
0
        internal IEnumerable <Point> Calculate()
        {
            if (BoundingBox.Width == 0)
            {
                FillBoundingBoxWithSites();
            }
            Cdt cdt = new Cdt(cites, null, null);

            cdt.Run();
            var triangles = cdt.GetTriangles();

            foreach (var triangle in triangles)
            {
                AddVoronoiCite(triangle);
            }
            return(voronoiSiteTree.GetAllLeaves());
        }
        /// <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);
        }
示例#23
0
        private void TesselateUnderShape(Shape shape)
        {
            var polys = new List <Polyline>(shape.Children.Select(sh => (Polyline)sh.BoundaryCurve));

            polys.Add(shape.BoundaryCurve as Polyline);
            var cdt = new Cdt(shapesToInnerPoints[shape], polys, null);

            cdt.Run();
            Set <CdtTriangle> triangles = cdt.GetTriangles();

            cdt.SetInEdges();
            CleanUpTriangles(shape, ref triangles, cdt);
            foreach (var t in triangles)
            {
                AddTriangleToCanvas(t);
            }
        }
示例#24
0
        static void TestTriangulationOnSmallGraph(ArgsParser.ArgsParser parser)
        {
            var polyline = new Polyline(
                new Point(20.8211097717285, 40.9088821411133),
                new Point(21.4894065856934, 46.6845321655273),
                new Point(22.9755554199219, 41.3355484008789),
                new Point(20.8211097717285, 40.9088821411133));
            var polylines = new List <Polyline>();

            polylines.Add(polyline);
            var points   = new List <Point>();
            var centroid = new Point(21.7620239257813, 42.9763209025065);

            points.Add(centroid);
            var testCdt = new Cdt(points, polylines, null);

            testCdt.Run();
        }
        /// <summary>
        /// Computes the minimum spanning tree on a DT with given weights.
        /// </summary>
        /// <param name="cdt"></param>
        /// <param name="weights"></param>
        /// <returns></returns>
        static internal List <CdtEdge> GetMstOnCdt(Cdt cdt, Func <CdtEdge, double> weights)
        {
            var siteArray = cdt.PointsToSites.Values.ToArray();
            var siteIndex = new Dictionary <CdtSite, int>();

            for (int i = 0; i < siteArray.Length; i++)
            {
                siteIndex[siteArray[i]] = i;
            }

            Dictionary <IntPair, CdtEdge> intPairsToCdtEdges = GetEdges(siteArray, siteIndex);

            var graph = new BasicGraph <IEdge>(intPairsToCdtEdges.Keys, siteArray.Length);

            var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weights(intPairsToCdtEdges[(IntPair)intPair]), 0);

            return(new List <CdtEdge>(mstOnBasicGraph.GetTreeEdges().Select(e => intPairsToCdtEdges[(IntPair)e])));
        }
示例#26
0
文件: CdtEdge.cs 项目: sta1216/MsAGL
        ///<summary>
        ///</summary>
        ///<param name="a"></param>
        ///<param name="b"></param>
        public CdtEdge(CdtSite a, CdtSite b)
        {
            var above = Cdt.Above(a.Point, b.Point);

            if (above == 1)
            {
                upperSite = a;
                lowerSite = b;
            }
            else
            {
                Debug.Assert(above != 0);
                lowerSite = a;
                upperSite = b;
            }

            upperSite.AddEdgeToSite(this);
        }
        public void InitCdt()
        {
            InitSegmentTree();

            for (int i = 0; i < fixedRectangles.Length; i++)
            {
                Point p    = Round(fixedRectangles[i].Center);
                var   node = new TreeNode {
                    isFixed = true, rectId = i, rect = fixedRectangles[i], sitePoint = p, type = SiteType.RectFixed
                };
                if (nodeLabelsFixed != null)
                {
                    node.label = nodeLabelsFixed[i];
                }

                pointToTreeNode[p] = node;
                _rectNodesRtree.Add(node.rect, node);
                _fixedRectanglesTree.Add(fixedRectangles[i], node);
            }

            for (int i = 0; i < moveableRectangles.Length; i++)
            {
                Point p    = Round(moveableRectangles[i].Center);
                var   node = new TreeNode {
                    isFixed = false, rectId = i, rect = moveableRectangles[i], sitePoint = p, type = SiteType.RectMoveable
                };
                if (nodeLabelsMoveable != null)
                {
                    node.label = nodeLabelsMoveable[i];
                }

                pointToTreeNode[p] = node;
                _rectNodesRtree.Add(node.rect, node);
                _moveableRectanglesTree.Add(moveableRectangles[i], node);
            }

            var sites = pointToTreeNode.Keys.ToList();

            //AddSitesForBoxSegmentOverlaps(sites);

            cdt = new Cdt(sites, null, null);
            cdt.Run();
        }
示例#28
0
        private static HashSet <Tuple <int, int> > GetProximityEdges(Cdt cdt)
        {
            HashSet <Tuple <int, int> > proxEdges = new HashSet <Tuple <int, int> >();

            foreach (var triangle in cdt.GetTriangles())
            {
                foreach (var edge in triangle.Edges)
                {
                    int a = (int)edge.lowerSite.Owner;
                    int b = (int)edge.upperSite.Owner;
                    if (!proxEdges.Contains(Tuple.Create(a, b)) && !proxEdges.Contains(Tuple.Create(b, a)))
                    {
                        proxEdges.Add(Tuple.Create(a, b));
                    }
                }
            }

            return(proxEdges);
        }
        Set <CdtEdge> ThreadBoneEdgeThroughCdt(SdBoneEdge boneEdge)
        {
            var start           = boneEdge.SourcePoint;
            var currentTriangle = boneEdge.Source.Triangle;

            Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle));
            var crossedEdges = new Set <CdtEdge>();
            var end          = boneEdge.TargetPoint;

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

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

            while (threader.MoveNext())
            {
                CdtEdge piercedEdge = threader.CurrentPiercedEdge;
                Debug.Assert(piercedEdge != null);
                if (Gates.Contains(piercedEdge))
                {
                    crossedEdges.Insert(piercedEdge);
                }
            }

            /*
             * CdtEdge piercedEdge = CdtIntersections.FindFirstPiercedEdge(currentTriangle, start, end, out negativeSign, out positiveSign, this.Cdt );
             * Debug.Assert(piercedEdge != null);
             *
             * do {
             *  if (Gates.Contains(piercedEdge))
             *      crossedEdges.Insert(piercedEdge);
             * }
             * while (CdtIntersections.FindNextPierced(start, end, ref currentTriangle, ref piercedEdge, ref negativeSign, ref positiveSign));
             */
            //if(ddd(boneEdge))
            //CdtSweeper.ShowFront(Cdt.GetTriangles(),null,new []{new LineSegment(boneEdge.SourcePoint,boneEdge.TargetPoint)}, crossedEdges.Select(e=>new LineSegment(e.upperSite.Point,e.lowerSite.Point)));

            return(crossedEdges);
        }
 internal SdShortestPath(Func <EdgeGeometry, List <Shape> > makeTransparentShapesOfEdgeGeometryAndGetTheShapes, Cdt cdt, Set <CdtEdge> gates)
 {
     MakeTransparentShapesOfEdgeGeometry = makeTransparentShapesOfEdgeGeometryAndGetTheShapes;
     Cdt   = cdt;
     Gates = gates;
 }