Example #1
0
        public static GeometryGraph CopyGraph(GeometryGraph graph)
        {
            if (graph == null) return null;
            var copy = new GeometryGraph();

            Dictionary<Node,Node> nodeCopy=new Dictionary<Node, Node>(graph.Nodes.Count);

            foreach (Node node in graph.Nodes) {
                var c = new Node();
                copy.Nodes.Add(c);
                nodeCopy[node] = c;
                c.BoundaryCurve = node.BoundaryCurve.Clone();
            }

            foreach (Edge edge in graph.Edges) {
                var source = edge.Source;
                var target = edge.Target;
                var copySource = nodeCopy[source];
                var copyTarget = nodeCopy[target];
                Edge edgeCopy=new Edge(copySource,copyTarget);
                copy.Edges.Add(edgeCopy);
                StraightLineEdges.RouteEdge(edgeCopy,0);
            }

            return copy;
        }
 private Node GetOrCreateNode(Port port, Dictionary<ICurve, Node> nodeDictionary) {
     var curve = GetPortCurve(port);
     Node node;
     if (!nodeDictionary.TryGetValue(curve, out node))
         nodeDictionary[curve] = node = new Node(curve);
     return node;
 }
        /// <summary>
        /// Executes the algorithm.
        /// </summary>
        protected override void  RunInternal()
        {
            Result = new double[pivotArray.Length][];

            Node[] nodes = new Node[graph.Nodes.Count];
            graph.Nodes.CopyTo(nodes, 0);
            double[] min = new double[graph.Nodes.Count];
            for (int i = 0; i < min.Length; i++)
            {
                min[i] = Double.PositiveInfinity;
            }
            Node pivot = nodes[0];
            pivotArray[0] = 0;
            for (int i = 0; ; i++) {
                var ssd = new SingleSourceDistances(graph, pivot, directed);
                ssd.Run();
                Result[i] = ssd.Result;
                if (i + 1 < pivotArray.Length)
                {//looking for the next pivot
                    int argmax = 0;
                    for (int j = 0; j < Result[i].Length; j++)
                    {
                        min[j] = Math.Min(min[j], Result[i][j]);
                        if (min[j] > min[argmax])
                            argmax = j;
                    }
                    pivot = nodes[argmax];
                    pivotArray[i + 1] = argmax;
                }
                else
                    break;
            }

        }
        public void SimpleDeepTranslationTest()
        {
            var graph = new GeometryGraph();
            var a = new Node(CurveFactory.CreateRectangle(30, 20, new Point()));
            var b = new Node(CurveFactory.CreateRectangle(30, 20, new Point(100, 0)));
            var e = new Edge(a, b);
            graph.Nodes.Add(a);
            graph.Nodes.Add(b);
            graph.Edges.Add(e);
            var c = CreateCluster(new Node[] { a, b }, 10);
            c.CalculateBoundsFromChildren(0);
            var originalClusterBounds = c.BoundingBox;
            RouteEdges(graph, 10);
            var edgeBounds = e.BoundingBox;

            Assert.AreEqual(c.BoundingBox.Width, 150, "Cluster has incorrect width");
            Assert.AreEqual(c.BoundingBox.Height, 40, "Cluster has incorrect width");

            var delta = new Point(10, 20);
            c.DeepTranslation(delta, true);
            Rectangle translatedClusterBounds = c.BoundingBox;

            Assert.IsTrue(ApproximateComparer.Close((translatedClusterBounds.LeftBottom - originalClusterBounds.LeftBottom), delta), "edge was not translated");

            c.CalculateBoundsFromChildren(0);

            Assert.IsTrue(ApproximateComparer.Close(translatedClusterBounds, c.BoundingBox), "translated bounds do not equal computed bounds of translated cluster");
            Assert.IsTrue(ApproximateComparer.Close((e.BoundingBox.LeftBottom - edgeBounds.LeftBottom), delta), "edge was not translated");
        }
 public HorizontalSeparationConstraint(Node u, Node v, double separation, bool equality)
 {
     this.equality = equality;
     this.u = u;
     this.v = v;
     this.separation = separation;
 }
Example #6
0
        internal static GeometryGraph CreateAndLayoutGraph()
        {
            double w = 30;
            double h = 20;
            GeometryGraph graph = new GeometryGraph();
            Node a = new Node( new Ellipse(w, h, new P()),"a");
            Node b = new Node( CurveFactory.CreateRectangle(w, h, new P()),"b");
            Node c = new Node( CurveFactory.CreateRectangle(w, h, new P()),"c");
            Node d = new Node(CurveFactory.CreateRectangle(w, h, new P()), "d");

            graph.Nodes.Add(a);
            graph.Nodes.Add(b);
            graph.Nodes.Add(c);
            graph.Nodes.Add(d);
            Edge e = new Edge(a, b) { Length = 10 };
            graph.Edges.Add(e);
            graph.Edges.Add(new Edge(b, c) { Length = 3 });
            graph.Edges.Add(new Edge(b, d) { Length = 4 });

            //graph.Save("c:\\tmp\\saved.msagl");
            var settings = new Microsoft.Msagl.Layout.MDS.MdsLayoutSettings();
            LayoutHelpers.CalculateLayout(graph, settings, null);

            return graph;
        }
 /// <summary>
 /// Validate two nodes not overlapping with each other
 /// </summary>        
 internal static void ValidateNoNodeOverlapping(Node node, Node node2)
 {
     if (node == node2 || node is Cluster || node2 is Cluster)
     {
         return;
     }
     Assert.IsFalse(node.BoundingBox.Intersects(node2.BoundingBox), string.Format("Node (ID: {0}, BoundingBox: {1}) overlaps with Node (ID: {2}, BoundingBox: {3})", node.UserData, node.BoundingBox.ToString(), node2.UserData, node2.BoundingBox.ToString()));            
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pushedNodes">nodes that are being pushed</param>
        /// <param name="separation"></param>
        /// <param name="pushingNodes"></param>
        public BumperPusher(IEnumerable<Node> pushedNodes, double separation, Node[] pushingNodes) {
            this.separation = separation;
            rtree = new RTree<Node>(RectangleNode<Node>.CreateRectangleNodeOnEnumeration(
                pushedNodes.Select(n => new RectangleNode<Node>(n, GetPaddedBoxOfNode(n)))));

            //LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(rtree.GetAllLeaves().Select(n=>new DebugCurve(n.BoundaryCurve)));
            this.pushingNodes = pushingNodes;
        }
  void Visit(Node u)
 {
     visited.Add(u);
     low[u] = depth[u] = visited.Count;
     foreach (var e in u.OutEdges.Concat(u.InEdges))
     {
         Visit(u, e);
     }
 }
 /// <summary>
 /// positions location nodes
 /// </summary>
 /// <param name="locationNodes">the nodes represent the labels and originally are positioned at locations</param>
 /// <param name="locationRadius">the minimum gap between a location and its label</param>
 /// <param name="removeCrossings">If set to true will remove intersections between line segments (location, locationLabel). 
 /// The result will be better but the calculation will take more time.
 /// </param>
 public static GeometryGraph PositionLabels(Node[] locationNodes, double locationRadius, bool routeEdges, double labelSeparation)
 {
     #if MYDEBUG
     Microsoft.Msagl.GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions();
     #endif
     var labeler = new LocationLabeler(locationNodes, locationRadius, routeEdges, labelSeparation);
     labeler.Work();
     return labeler.graph;
 }
 public ShortestPartRouterForLg(Node source, Node target, Func<Node, LgNodeInfo> geomNodeToLgNode) {
     this.source = source;
     this.target = target;
     this.geomNodeToLgNode = geomNodeToLgNode;
     queue.Enqueue(source, 0);
     pathDirection = target.Center - source.Center;
     costToTarget = double.PositiveInfinity;
     EdgeIsInterestingFunc = MonotonicityFunc;
 }
        static void CreateShapeIfNeeeded(Node n, Dictionary<Node, Shape> nodesToShapes) {
            if (nodesToShapes.ContainsKey(n)) return;
            nodesToShapes[n] = new RelativeShape(() => n.BoundaryCurve)
#if DEBUG
        {
                        UserData = n.ToString()
        }
#endif       
                ;
        }
 IEnumerable<Node> PushByNodeAndReportPushedAsFixed(Node pushingNode) {
     var ret = new List<Node>();
     var pushingNodeBox = GetPaddedBoxOfNode(pushingNode);
     foreach (var rectNode in rtree.GetAllLeavesIntersectingRectangle(pushingNodeBox)) {
         if (fixedNodes.Contains(rectNode.UserData)) continue;
         if (PushNodeAndUpdateRTree(pushingNode, rectNode))
             ret.Add(rectNode.UserData);
     }
     return ret;
 }
        public void IsDescendantOf_BasicTest()
        {
            Cluster cluster = new Cluster();
            Node node = new Node();
            Node node2 = new Node();
            cluster.AddChild(node);

            Assert.IsTrue(node.IsDescendantOf(cluster), "Node is a descendant of cluster but IsDescendantOf returns false.");
            Assert.IsFalse(node2.IsDescendantOf(cluster), "Node2 is not a descendant of cluster but IsDescendantOf returns true.");
            Assert.IsFalse(cluster.IsDescendantOf(cluster), "A cluster should not be considered a descendant of itself.");
        }
 static void ProcessAncestorDescendantCouple(Cluster ancestor, Node node, Dictionary<Node, Shape> nodesToShapes) {
     Cluster parent=Parent(node);
     do {
         foreach (var n in Children(parent))
             CreateShapeIfNeeeded(n, nodesToShapes);
         if (parent == ancestor)
             break;
         parent = Parent(parent);                
     } while (true);
     CreateShapeIfNeeeded(parent, nodesToShapes);
 }
        GeometryGraph CreateGeometryGraph(PreGraph preGraph) {
            var graph = new GeometryGraph();
            var nodeDictionary = new Dictionary<ICurve, Node>();
            foreach (var curve in preGraph.nodeBoundaries) {
                var node = new Node(curve);
                nodeDictionary[curve] = node;
                graph.Nodes.Add(node);
            }
            foreach (var eg in preGraph.edgeGeometries)
                AddEdgeGeometryToGraph(eg, graph, nodeDictionary);

            return graph;
        }
        public static GeometryGraph CreateComplex()
        {
            GeometryGraph graph = new GeometryGraph();
            var nodeInD = new Node();
            graph.Nodes.Add(nodeInD);
            var nodePrecursor = new Node();
            graph.Nodes.Add(nodePrecursor);
            var nodeEarlyMeiosis = new Node();
            graph.Nodes.Add(nodeEarlyMeiosis);
            var nodeMeiosis = new Node();
            graph.Nodes.Add(nodeMeiosis);



            return graph;
        }
 /// <summary>
 /// Place node at the centroid of its neighbours and its initial position
 /// </summary>
 /// <param name="u">node to center</param>
 private static void CenterNode(Node u)
 {
     var c = u.Center;
     int count = 1;
     foreach (var e in u.InEdges)
     {
         c += e.Source.Center;
         ++count;
     }
     foreach (var e in u.OutEdges)
     {
         c += e.Target.Center;
         ++count;
     }
     Random r = new Random();
     c += new Point(r.NextDouble(), r.NextDouble());
     u.Center = c / count;
 }
        /// <summary>
        /// Creates a shape with a RelativeFloatingPort for the node center, attaches it to the shape and all edges
        /// </summary>
        /// <param name="node"></param>
        /// <returns>Shape obstacle for the node with simple port</returns>
        static Shape CreateShapeWithCenterPort(Node node)
        {
            // Debug.Assert(ApproximateComparer.Close(node.BoundaryCurve.BoundingBox, node.BoundingBox), "node's curve doesn't fit its bounds!");
            var shape = new RelativeShape(() => node.BoundaryCurve);
            var port = new RelativeFloatingPort(() => node.BoundaryCurve, () => node.Center);
            shape.Ports.Insert(port);
            foreach (var e in node.InEdges)
                FixPortAtTarget(shape, port, e);
            foreach (var e in node.OutEdges)
                FixPortAtSource(shape, port, e);
            foreach (var e in node.SelfEdges) {
               FixPortAtSource(shape, port, e);
               FixPortAtTarget(shape, port, e);
            }
#if DEBUG
           // shape.UserData = node.ToString();
#endif
            return shape;
        }
        public void IsDescendantOf_ManyParents()
        {
            Cluster grandMother = new Cluster();
            Cluster grandFather = new Cluster();
            Cluster parent = new Cluster();
            Cluster uncle = new Cluster();
            grandMother.AddChild(parent);
            grandMother.AddChild(uncle);
            grandFather.AddChild(parent);
            grandFather.AddChild(uncle);

            Node child = new Node();
            parent.AddChild(child);

            Assert.IsTrue(child.IsDescendantOf(parent), "The child node should be considered a descendant of its parent.");
            Assert.IsTrue(child.IsDescendantOf(grandMother), "The child node should be considered a descendant of its grandmother.");
            Assert.IsTrue(child.IsDescendantOf(grandFather), "The child node should be considered a descendant of its grandfather.");
            Assert.IsFalse(child.IsDescendantOf(uncle), "The child node should not be considered a descendant of its uncle.");
        }
  void Visit(Node u, Edge e)
 {
     Node v = e.Source == u ? e.Target : e.Source;
     if (!visited.Contains(v))
     {
         stack.Push(e);
         parent[v] = u;
         Visit(v);
         if (low[u] >= depth[u])
         {
             CreateComponent(e);
         }
         low[u] = Math.Min(low[u], low[v]);
     }
     else if (parent[u] != v && depth[v] < depth[u])
     {
         stack.Push(e);
         low[u] = Math.Min(low[u], depth[v]);
     }
 }
Example #22
0
        public Form1()
        {
            InitializeComponent();
            Node n0 = new Node( CurveFactory.CreateEllipse(10, 10, new Microsoft.Msagl.Core.Geometry.Point()),"a");
            Microsoft.Msagl.Core.Geometry.Point n1Center = new Microsoft.Msagl.Core.Geometry.Point(20, 0);
            Node n1 = new Node( CurveFactory.CreateEllipse(10, 10, n1Center),"b");
            n1.Center = n1Center;
            Microsoft.Msagl.Core.Geometry.Point n2Center = new Microsoft.Msagl.Core.Geometry.Point(5, 3);
            Node n2 = new Node( CurveFactory.CreateEllipse(10, 10, n2Center),"c");
            n2.Center = n2Center;

            Microsoft.Msagl.Core.Geometry.Point n3Center = new Microsoft.Msagl.Core.Geometry.Point(8, -1);
            Node n3 = new Node( CurveFactory.CreateEllipse(10, 10, n3Center),"d");
            n3.Center = n3Center;
            Microsoft.Msagl.Core.Geometry.Point n4Center = new Microsoft.Msagl.Core.Geometry.Point(6, -4);
            Node n4 = new Node( CurveFactory.CreateEllipse(10, 10, n4Center),"e");
            n4.Center = n4Center;

            Microsoft.Msagl.Core.Geometry.Point n5Center = new Microsoft.Msagl.Core.Geometry.Point(19, -3);
            Node n5 = new Node( CurveFactory.CreateEllipse(10, 10, n5Center),"f");
            n5.Center = n5Center;

            IncrementalLabeler il = new IncrementalLabeler(6, false, -1);
            #if MYDEBUG
            Microsoft.Msagl.GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions();
            #endif

            il.AddNode(n0);
            il.AddNode(n1);
            il.Layout();
            il.AddNode(n2);
            il.AddNode(n3);
            il.Layout();
            GeometryGraph graph = LocationLabeler.PositionLabels(new[] { n0, n1, n2, n3, n4, n5 }, 5, false, -1);

            //           var g=GeometryGraph.CreateFromFile("c:/tmp/graph");
               // ChangeShapes(g);
              //          var graph = LocationLabeler.PositionLabels(  g.Nodes , 6, false, -6);
        }
        bool PushNodeAndUpdateRTree(Node pushingNode, RectangleNode<Node> pushed) {
            var del = pushed.UserData.Center - pushingNode.Center;
            var w = pushingNode.Width / 2 + pushed.UserData.Width / 2;
            var h = pushingNode.Height / 2 + pushed.UserData.Height / 2;
            var absDelXBetweenCenters = Math.Abs(del.X);
            var absDelYBetweenCenters = Math.Abs(del.Y);

            var xSep = absDelXBetweenCenters - w;
            var ySep = absDelYBetweenCenters - h;
            if (xSep >= separation || ySep >= separation)
                return false;
            if (absDelXBetweenCenters >= absDelYBetweenCenters) {
                double d = del.X > 0 ? separation - xSep : xSep - separation;
                PushByX(d, pushed);
            }
            else {
                double d = del.Y > 0 ? separation - ySep : ySep - separation;
                PushByY(d, pushed);
            }
            UpdateBoundingBoxesOfPushedAndUpParents(pushed);
            return true;
        }
        /// <summary>
        /// Validate two nodes on same layer have valid separation between them
        /// </summary>
        internal static void ValidateIntraLayerNodeSeparation(Node node, Node node2, SugiyamaLayoutSettings settings)
        {

            if (node == node2 || node is Cluster || node2 is Cluster)
            {
                return;
            }
            if (OnSameLayer(node, node2, settings))
            {
                if (Math.Abs(node.Center.Y - node2.Center.Y) <= Tolerance)
                {
                    Rectangle left = node.BoundingBox;
                    Rectangle right = node2.BoundingBox;
                    Rectangle temp;
                    if (left.Left > right.Left)
                    {
                        temp = left;
                        left = right;
                        right = temp;
                    }
                    Assert.IsTrue(Math.Abs(right.Left - left.Right) >= settings.NodeSeparation, string.Format("Node (ID: {0}, BoundingBox: {1}) has less separation from Node (ID: {2}, BoundingBox: {3})", node.UserData, node.BoundingBox.ToString(), node2.UserData, node2.BoundingBox.ToString()));
                }
                else
                {
                    Rectangle top = node.BoundingBox;
                    Rectangle bottom = node2.BoundingBox;
                    Rectangle temp;
                    if (top.Top < bottom.Top)
                    {
                        temp = top;
                        top = bottom;
                        bottom = temp;
                    }
                    Assert.IsTrue(Math.Abs(top.Bottom - bottom.Top) >= settings.NodeSeparation, string.Format("Node (ID: {0}, BoundingBox: {1}) has less separation from Node (ID: {2}, BoundingBox: {3})", node.UserData, node.BoundingBox.ToString(), node2.UserData, node2.BoundingBox.ToString()));
                }
            }
        }
 /// <summary>
 /// constructor
 /// </summary>
 /// <param name="sourceP"></param>
 /// <param name="targetP"></param>
 public PhyloEdge(Node sourceP, Node targetP) : base(sourceP, targetP) { }
 public HorizontalSeparationConstraint(Node u, Node v, double separation)
 {
     this.u = u;
     this.v = v;
     this.separation = separation;
 }
 public static void DrawNode(Node n, Pen pen, Graphics graphics) {
     ICurve curve = n.BoundaryCurve;
     Ellipse el = curve as Ellipse;
     if (el != null) {
         graphics.DrawEllipse(pen, new RectangleF((float)el.BoundingBox.Left, (float)el.BoundingBox.Bottom,
             (float)el.BoundingBox.Width, (float)el.BoundingBox.Height));
     } else
         graphics.DrawPath(pen, CreateGraphicsPath(curve));
 }
 static private bool NodeIsALeaf(Node node) {
     return !node.OutEdges.GetEnumerator().MoveNext();
 }
 void WriteNodeIpe(Node node)
 {
     string id;
     if (!nodeIds.TryGetValue(node, out id))
         nodeIds[node] = id = nodeIds.Count.ToString();
     // todo: add Id as text
     if (node.BoundaryCurve != null)
     {
         WriteICurveIpe(node.BoundaryCurve);
         WriteLabelIpe(node.BoundaryCurve.BoundingBox.Center, "" + id);
     }
 }
 void WriteNode(Node node) {
     string id;
     if (!nodeIds.TryGetValue(node, out id))
         nodeIds[node] = id = nodeIds.Count.ToString();
     WriteStartElement(GeometryToken.Node);
     WriteAttribute(GeometryToken.Id, id);
     if (node.Padding != GeometryGraphReader.NodeDefaultPadding)
         WriteAttribute(GeometryToken.Padding, node.Padding);
     WriteICurve(node.BoundaryCurve);
     WriteEndElement();
 }