Esempio n. 1
0
 public override Point[] ComputeSingle(TEdge edge)
 {
     CalculateMatrix(CancellationToken.None); //maybe shouldnt do this cause can be used from algo storage and already inited
     SetupPathFinder();                       //
     ComputeER(edge, CancellationToken.None);
     return(EdgeRoutes.ContainsKey(edge) ? EdgeRoutes[edge] : null);
 }
Esempio n. 2
0
        public override void Compute()
        {
            if (VertexPositions == null || VertexPositions.Count < 3)
            {
                return;
            }
            foreach (var item in VertexPositions.Values)
            {
                _minPoint.X = Math.Min(item.X, _minPoint.X);
                _minPoint.Y = Math.Min(item.Y, _minPoint.Y);
                _maxPoint.X = Math.Max(item.X, _maxPoint.X);
                _maxPoint.Y = Math.Max(item.Y, _maxPoint.Y);
            }

            EdgeRoutes.Clear();

            calculateMatrix();
            setupPathFinder();


            foreach (var item in _graph.Edges)
            {
                ComputeER(item);
            }
        }
Esempio n. 3
0
        public override void Compute(CancellationToken cancellationToken)
        {
            if (VertexPositions == null || VertexPositions.Count < 3)
            {
                return;
            }
            foreach (var item in VertexPositions.Values)
            {
                cancellationToken.ThrowIfCancellationRequested();

                _minPoint.X = Math.Min(item.X, _minPoint.X);
                _minPoint.Y = Math.Min(item.Y, _minPoint.Y);
                _maxPoint.X = Math.Max(item.X, _maxPoint.X);
                _maxPoint.Y = Math.Max(item.Y, _maxPoint.Y);
            }

            EdgeRoutes.Clear();

            CalculateMatrix(cancellationToken);
            SetupPathFinder();


            foreach (var item in Graph.Edges)
            {
                ComputeER(item, cancellationToken);
            }
        }
Esempio n. 4
0
        private void ComputeER(TEdge item, CancellationToken cancellationToken)
        {
            var startPt = GetClosestPoint(_validPoints, VertexPositions[item.Source]);
            var endPt   = GetClosestPoint(_validPoints, VertexPositions[item.Target]);
            var lst     = _pathFinder.FindPath(startPt, endPt);

            if (lst == null)
            {
                return;
            }
            var ptlst = new List <Point>();

            foreach (var pt in lst)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var mi = _resMatrix[pt.X, pt.Y];
                ptlst.Add(mi.Point);
            }
            if (EdgeRoutes.ContainsKey(item))
            {
                EdgeRoutes[item] = ptlst.ToArray();
            }
            else
            {
                EdgeRoutes.Add(new KeyValuePair <TEdge, Point[]>(item, ptlst.ToArray()));
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Bundles edges of the graph.
        /// </summary>
        ///
        /// <param name="graph">
        /// Graph whose edges should be bundled
        /// </param>
        ///
        /// <param name="rectangle">
        /// Rectangle in which the graph is laid out.
        /// Control points of bundled edges should not fall outside of this rectangle.
        /// </param>
        public void BundleAllEdges(TGraph graph)
        {
            EdgeRoutes.Clear();

            //this.rectangle = rectangle;
            directed = true; // as we use bidirectional by default

            AddDataForAllEdges(graph.Edges);

            //Stopwatch sw = new Stopwatch();
            //sw.Start();

            FindCompatibleEdges(edgeGroupData);

            //sw.Stop();


            DivideAllEdges(subdivisionPoints);

            //sw = new Stopwatch();
            //sw.Start();

            for (var i = 0; i < iterations; i++)
            {
                MoveControlPoints(edgeGroupData);
            }

            //prevents oscillating movements
            for (var i = 0; i < 5; i++)
            {
                cooldown *= 0.5f;
                MoveControlPoints(edgeGroupData);
            }

            //sw.Stop();

            cooldown = 1f;

            if (straightening > 0)
            {
                StraightenEdgesInternally(edgeGroupData, straightening);
            }

            foreach (var e in graph.Edges)
            {
                if (!e.IsSelfLoop)
                {
                    var key   = new KeyPair(e.Source.ID, e.Target.ID);
                    var list2 = edgeGroupData[key].controlPoints.ToList();

                    //Point p1 = GeometryHelper.GetEdgeEndpointOnRectangle(VertexPositions[e.Source], VertexSizes[e.Source], list2.First());
                    //Point p2 = GeometryHelper.GetEdgeEndpointOnRectangle(VertexPositions[e.Target], VertexSizes[e.Target], list2.Last());
                    //list2.Insert(0, p1); list2.Add(p2);
                    list2.Insert(0, list2.First()); list2.Add(list2.Last());

                    EdgeRoutes.Add(e, list2.ToArray());
                }
            }
        }
Esempio n. 6
0
 public override void Compute(CancellationToken cancellationToken)
 {
     EdgeRoutes.Clear();
     foreach (var item in Graph.Edges)
     {
         EdgeRoutingTest(item, cancellationToken);
     }
 }
Esempio n. 7
0
 public override void Compute()
 {
     EdgeRoutes.Clear();
     foreach (var item in _graph.Edges)
     {
         EdgeRoutingTest(item);
     }
 }
Esempio n. 8
0
 public override void Compute(CancellationToken cancellationToken)
 {
     EdgeRoutes.Clear();
     foreach (var edge in Graph.Edges)
     {
         EdgeRoutes.Add(edge, ComputeSingle(edge));
     }
 }
Esempio n. 9
0
 public override Point[] ComputeSingle(TEdge edge)
 {
     BundleEdges(_graph, new List <TEdge>()
     {
         edge
     });
     return(EdgeRoutes.ContainsKey(edge) ? EdgeRoutes[edge] : null);
 }
Esempio n. 10
0
        /// <summary>
        /// Bundles specified edges. Shapes of all the other edges remain the same,
        /// so this method is faster than the one for bundling all edges, but also produces less optimal layout.
        /// </summary>
        ///
        /// <param name="graph">
        /// Parent graph of the edge set
        /// </param>
        ///
        /// <param name="edges">
        /// Edges that should be bundled
        /// </param>
        ///
        /// <param name="rectangle">
        /// Rectangle in which the graph is laid out.
        /// Control points of bundled edges should not fall outside of this rectangle.
        /// </param>
        public void BundleEdges(TGraph graph, IEnumerable <TEdge> edges)
        {
            directed = true;

            AddAllExistingData(graph.Edges);
            AddEdgeDataForMovedEdges(edges);
            FindCompatibleEdges(movedEdgeGroupData);
            ResetMovedEdges();

            for (var i = 0; i < iterations; i++)
            {
                MoveControlPoints(movedEdgeGroupData);
            }

            for (var i = 0; i < 5; i++)
            {
                cooldown *= 0.5f;
                MoveControlPoints(movedEdgeGroupData);
            }

            cooldown = 1f;

            if (straightening > 0)
            {
                StraightenEdgesInternally(movedEdgeGroupData, straightening);
            }

            foreach (var e in edges)
            {
                EdgeGroupData ed;
                var           key = new KeyPair(e.Source.ID, e.Target.ID);
                movedEdgeGroupData.TryGetValue(key, out ed);
                if (ed != null)
                {
                    var list2 = ed.controlPoints.ToList();

                    //Point p1 = GeometryHelper.GetEdgeEndpointOnRectangle(VertexPositions[e.Source], VertexSizes[e.Source], list2.First());
                    //Point p2 = GeometryHelper.GetEdgeEndpointOnRectangle(VertexPositions[e.Target], VertexSizes[e.Target], list2.Last());
                    //list2.Insert(0, p1); list2.Add(p2);
                    if (list2.Count > 0)
                    {
                        list2.Insert(0, list2.First());
                        list2.Add(list2.Last());
                    }

                    if (EdgeRoutes.ContainsKey(e))
                    {
                        EdgeRoutes[e] = list2.ToArray();
                    }
                    else
                    {
                        EdgeRoutes.Add(e, list2.ToArray());
                    }
                }
                //e.SetValue(ReservedMetadataKeys.PerEdgeIntermediateCurvePoints, ed.controlPoints);
            }
        }
        /// <inheritdoc />
        public override void Calculate()
        {
            var topLeft     = new Point(double.PositiveInfinity, double.PositiveInfinity);
            var bottomRight = new Point(double.NegativeInfinity, double.NegativeInfinity);

            foreach (TVertex vertex in Graph.Vertices)
            {
                Point pos  = Positions[vertex];
                Size  size = Sizes[vertex];
                topLeft.X = Math.Min(pos.X - size.Width / 2.0, topLeft.X);
                topLeft.Y = Math.Min(pos.Y - size.Height / 2.0, topLeft.Y);

                bottomRight.X = Math.Max(pos.X + size.Width / 2.0, bottomRight.X);
                bottomRight.Y = Math.Max(pos.Y + size.Height / 2.0, bottomRight.Y);
            }

            foreach (TEdge edge in Graph.Edges)
            {
                if (!EdgeRoutes.TryGetValue(edge, out Point[] routePoints) ||
Esempio n. 12
0
        public override void Calculate()
        {
            Point topLeft     = new Point(double.PositiveInfinity, double.PositiveInfinity);
            Point bottomRight = new Point(double.NegativeInfinity, double.NegativeInfinity);

            foreach (var v in Graph.Vertices)
            {
                Point p = Positions[v];
                Size  s = Sizes[v];
                topLeft.X = Math.Min(p.X - s.Width / 2.0, topLeft.X);
                topLeft.Y = Math.Min(p.Y - s.Height / 2.0, topLeft.Y);

                bottomRight.X = Math.Max(p.X + s.Width / 2.0, bottomRight.X);
                bottomRight.Y = Math.Max(p.Y + s.Height / 2.0, bottomRight.Y);
            }

            foreach (var e in Graph.Edges)
            {
                Point[] routePoints = null;
                if (!EdgeRoutes.TryGetValue(e, out routePoints) || routePoints == null || routePoints.Length == 0)
                {
                    continue;
                }

                for (int i = 0; i < routePoints.Length; i++)
                {
                    Point p = routePoints[i];
                    topLeft.X = Math.Min(p.X, topLeft.X);
                    topLeft.Y = Math.Min(p.Y, topLeft.Y);

                    bottomRight.X = Math.Max(p.X, bottomRight.X);
                    bottomRight.Y = Math.Max(p.Y, bottomRight.Y);
                }
            }

            Vector layoutAreaSize = bottomRight - topLeft;

            Area  = layoutAreaSize.LengthSquared;
            Ratio = layoutAreaSize.X / layoutAreaSize.Y;
        }
Esempio n. 13
0
        public override void Compute(CancellationToken cancellationToken)
        {
            foreach (var edge in Graph.Edges)
            {
                var sourcePosition = VertexPositions[edge.Source];
                var targetPosition = VertexPositions[edge.Target];
                var sourceSize     = VertexSizes[edge.Source];
                var targetSize     = VertexSizes[edge.Target];

                if (sourcePosition.X != targetPosition.X)
                {
                    EdgeRoutes.Add(
                        edge,
                        new[]
                    {
                        new Point(0, 0),
                        new Point(targetPosition.X + targetSize.Width / 2, sourcePosition.Y + sourceSize.Height / 2),
                        new Point(0, 0)
                    });
                }
            }
        }
Esempio n. 14
0
        private void EdgeRoutingTest(TEdge ctrl, CancellationToken cancellationToken)
        {
            //bad edge data check
            if (ctrl.Source.ID == -1 || ctrl.Target.ID == -1)
            {
                throw new GX_InvalidDataException("SimpleEdgeRouting() -> You must assign unique ID for each vertex to use SimpleER algo!");
            }
            if (ctrl.Source.ID == ctrl.Target.ID || !VertexSizes.ContainsKey(ctrl.Source) || !VertexSizes.ContainsKey(ctrl.Target))
            {
                return;
            }

            var ss         = VertexSizes[ctrl.Source];
            var es         = VertexSizes[ctrl.Target];
            var startPoint = new Point(ss.X + ss.Width * 0.5, ss.Y + ss.Height * 0.5);
            var endPoint   = new Point(es.X + es.Width * 0.5, es.Y + es.Height * 0.5);

            if (startPoint == endPoint)
            {
                return;
            }

            var originalSizes = getSizesCollection(ctrl, endPoint);
            var checklist     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);
            var leftSizes     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);


            var tempList = new List <Point>();

            tempList.Add(startPoint);

            bool haveIntersections = true;

            //while we have some intersections - proceed
            while (haveIntersections)
            {
                var curDrawback = drawback_distance;
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var item = checklist.Keys.FirstOrDefault();
                    //set last route point as current start point
                    startPoint = tempList.Last();
                    if (item == null)
                    {
                        //checked all vertices and no intersection was found - quit
                        haveIntersections = false;
                        break;
                    }
                    else
                    {
                        var   r = originalSizes[item].Value;
                        Point checkpoint;
                        //check for intersection point. if none found - remove vertex from checklist
                        if (GetIntersectionPoint(r, startPoint, endPoint, out checkpoint) == -1)
                        {
                            checklist.Remove(item); continue;
                        }
                        var    mainVector = new Vector(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y);
                        double X = 0; double Y = 0;
                        //calculate drawback X coordinate
                        if (startPoint.X == checkpoint.X || Math.Abs(startPoint.X - checkpoint.X) < curDrawback)
                        {
                            X = startPoint.X;
                        }
                        else if (startPoint.X < checkpoint.X)
                        {
                            X = checkpoint.X - curDrawback;
                        }
                        else
                        {
                            X = checkpoint.X + curDrawback;
                        }
                        //calculate drawback Y coordinate
                        if (startPoint.Y == checkpoint.Y || Math.Abs(startPoint.Y - checkpoint.Y) < curDrawback)
                        {
                            Y = startPoint.Y;
                        }
                        else if (startPoint.Y < checkpoint.Y)
                        {
                            Y = checkpoint.Y - curDrawback;
                        }
                        else
                        {
                            Y = checkpoint.Y + curDrawback;
                        }
                        //set drawback checkpoint
                        checkpoint = new Point(X, Y);
                        bool isStartPoint = checkpoint == startPoint;

                        bool routeFound        = false;
                        bool viceversa         = false;
                        int  counter           = 1;
                        var  joint             = new Point();
                        bool?blocked_direction = null;
                        while (!routeFound)
                        {
                            cancellationToken.ThrowIfCancellationRequested();

                            //choose opposite vector side each cycle
                            var signedDistance = viceversa ? side_distance : -side_distance;
                            //get new point coordinate
                            joint = new Point(
                                checkpoint.X + signedDistance * counter * (mainVector.Y / mainVector.Length),
                                checkpoint.Y - signedDistance * counter * (mainVector.X / mainVector.Length));

                            //now check if new point is in some other vertex
                            var iresult     = false;
                            var forcedBreak = false;
                            if (originalSizes.Any(sz => sz.Value.Value.Contains(joint)))
                            {
                                iresult = true;
                                //block this side direction
                                if (blocked_direction == null)
                                {
                                    blocked_direction = viceversa;
                                }
                                else
                                {
                                    //both sides blocked - need to drawback
                                    forcedBreak = true;
                                }
                            }
                            if (forcedBreak)
                            {
                                break;
                            }

                            //get vector intersection if its ok
                            if (!iresult)
                            {
                                iresult = IsIntersected(r, joint, endPoint);
                            }

                            //if no vector intersection - we've found it!
                            if (!iresult)
                            {
                                routeFound        = true;
                                blocked_direction = null;
                            }
                            else
                            {
                                //still have an intersection with current vertex
                                haveIntersections = true;
                                //skip point search if too many attempts was made (bad logic hack)
                                if (counter > 300)
                                {
                                    break;
                                }
                                counter++;
                                //switch vector search side
                                if (blocked_direction == null || (blocked_direction == viceversa))
                                {
                                    viceversa = !viceversa;
                                }
                            }
                        }

                        //if blocked and this is not start point (nowhere to drawback) - then increase drawback distance
                        if (blocked_direction != null && !isStartPoint)
                        {
                            //search has been blocked - need to drawback
                            curDrawback += drawback_distance;
                        }
                        else
                        {
                            //add new route point if we found it
                            // if(routeFound)
                            tempList.Add(joint);
                            leftSizes.Remove(item);
                        }
                    }
                    //remove currently evaded obstacle vertex from the checklist
                    checklist.Remove(item);
                }
                //assign possible left vertices as a new checklist if any intersections was found
                if (haveIntersections)
                {
                    checklist = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(leftSizes);
                }
            }
            //finally, add an end route point

            tempList.Add(endPoint);


            if (EdgeRoutes.ContainsKey(ctrl))
            {
                EdgeRoutes[ctrl] = tempList.Count > 2 ? tempList.ToArray() : null;
            }
            else
            {
                EdgeRoutes.Add(ctrl, tempList.Count > 2 ? tempList.ToArray() : null);
            }
        }
Esempio n. 15
0
 public override Point[] ComputeSingle(TEdge edge)
 {
     EdgeRoutingTest(edge, CancellationToken.None);
     return(EdgeRoutes.ContainsKey(edge) ? EdgeRoutes[edge] : null);
 }
Esempio n. 16
0
        /// <inheritdoc />
        public override void Calculate()
        {
            TEdge[] edges      = Graph.Edges.ToArray();
            var     edgePoints = new List <Point> [edges.Length];

            // Create the points of the edges
            for (int i = 0; i < edges.Length; ++i)
            {
                TEdge        edge   = edges[i];
                List <Point> points = EdgeRoutes.TryGetValue(edge, out Point[] route) && route != null && route.Length > 0
                    ? new List <Point>(route.Length + 2)
                    : new List <Point>(2);

                points.Add(Positions[edge.Source]);
                if (route != null && route.Length > 0)
                {
                    points.AddRange(route);
                }
                points.Add(Positions[edge.Target]);

                edgePoints[i] = points;

                for (int j = 1; j < points.Count; ++j)
                {
                    double length = (points[j] - points[j - 1]).Length;

                    MinimumEdgeLength  = Math.Min(MinimumEdgeLength, length);
                    MaximumEdgeLength  = Math.Max(MaximumEdgeLength, length);
                    AverageEdgeLength += length;
                }
            }

            // Check the crosses
            for (int i = 0; i < edges.Length - 1; ++i)
            {
                for (int j = i + 1; j < edges.Length; ++j)
                {
                    List <Point> edgePoints1 = edgePoints[i];
                    List <Point> edgePoints2 = edgePoints[j];

                    for (int ii = 0; ii < edgePoints1.Count - 1; ++ii)
                    {
                        Point pA = edgePoints1[ii];
                        Point pB = edgePoints1[ii + 1];

                        for (int jj = 0; jj < edgePoints2.Count - 1; ++jj)
                        {
                            Point pC = edgePoints2[jj];
                            Point pD = edgePoints2[jj + 1];

                            if (pB.Equals(pC) || pA.Equals(pC) || pA.Equals(pD) || pB.Equals(pD))
                            {
                                continue;   // Ignore if source and/or target are the same
                            }
                            // [AB]
                            double xA = pA.X;
                            double yA = pA.Y;
                            double xB = pB.X;
                            double yB = pB.Y;

                            // [CD]
                            double xC = pC.X;
                            double yC = pC.Y;
                            double xD = pD.X;
                            double yD = pD.Y;

                            // The edges crosses each other
                            bool segmentCrossing =
                                ((xC - xA) * (yB - yA) + (yC - yA) * (xA - xB) < 0) ^
                                ((xD - xA) * (yB - yA) + (yD - yA) * (xA - xB) < 0)
                                &&
                                ((xA - xC) * (yD - yC) + (yA - yC) * (xC - xD) < 0) ^
                                ((xB - xC) * (yD - yC) + (yB - yC) * (xC - xD) < 0);

                            if (segmentCrossing)
                            {
                                ++CrossCount;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 17
0
        public override void Calculate()
        {
            var edges      = Graph.Edges.ToArray();
            var edgePoints = new List <Point> [edges.Length];

            int segmentCount = 0;

            //create the points of the edges
            for (int i = 0; i < edges.Length - 1; i++)
            {
                var          edge   = edges[i];
                Point[]      route  = null;
                List <Point> points = null;
                if (EdgeRoutes.TryGetValue(edge, out route) && route != null && route.Length > 0)
                {
                    points = new List <Point>(route.Length + 2);
                }
                else
                {
                    points = new List <Point>(2);
                }
                points.Add(Positions[edge.Source]);
                if (route != null && route.Length > 0)
                {
                    points.AddRange(route);
                }
                points.Add(Positions[edge.Target]);

                for (int j = 0; j < points.Count - 1; j++)
                {
                    double length = (points[j] - points[j - 1]).Length;

                    MinimumEdgeLength  = Math.Min(MinimumEdgeLength, length);
                    MaximumEdgeLength  = Math.Max(MaximumEdgeLength, length);
                    AverageEdgeLength += length;
                    segmentCount      += 1;
                }
            }

            //check the crosses
            for (int i = 0; i < edges.Length - 1; i++)
            {
                for (int j = i + 1; j < edges.Length; j++)
                {
                    List <Point> edgePoints1 = edgePoints[i];
                    List <Point> edgePoints2 = edgePoints[j];

                    for (int ii = 0; ii < edgePoints1.Count - 1; ii++)
                    {
                        var p11 = edgePoints1[ii];
                        var p12 = edgePoints1[ii + 1];
                        if (p12.X < p11.X)
                        {
                            Point p = p12;
                            p12 = p11;
                            p11 = p;
                        }
                        for (int jj = 0; jj < edgePoints2.Count - 1; jj++)
                        {
                            var p21 = edgePoints2[jj];
                            var p22 = edgePoints2[jj + 1];
                            if (p22.X < p21.X)
                            {
                                Point p = p22;
                                p22 = p21;
                                p21 = p22;
                            }

                            p11.X = p21.X = Math.Max(p11.X, p21.X);
                            p12.X = p22.X = Math.Min(p12.X, p22.X);

                            if ((p11.Y - p21.Y) * (p12.Y - p22.Y) < 0)
                            {
                                //the edges crosses each other
                                CrossCount += 1;

                                Vector v1 = p11 - p12;
                                Vector v2 = p21 - p22;

                                double angle = Math.Acos(Math.Abs((v1.X * v2.X + v1.Y * v2.Y) / (v1.Length * v2.Length)));

                                MinimumAngle  = Math.Min(MinimumAngle, angle);
                                MaximumAngle  = Math.Max(MaximumAngle, angle);
                                AverageAngle += angle;
                            }
                        }
                    }
                }
            }

            AverageAngle      /= segmentCount;
            AverageEdgeLength /= segmentCount;
        }