/// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 public void RemoveOverlaps(GeometryGraph graph)
 {
     Graph = graph;
     RemoveOverlaps();
 }
예제 #2
0
        /// <summary>
        /// Example on how to use Stress Majorization with a small graph and Localized method.
        /// </summary>
        public static void RunStressMajorizationExample()
        {
            //create a star graph where three nodes are connected to the center
            GeometryGraph graph = new GeometryGraph();

            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());

            //set initial positions, e.g., random
            graph.Nodes[0].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(5, 5));
            graph.Nodes[1].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(7, 10));
            graph.Nodes[2].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(7, 2));
            graph.Nodes[3].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(35, 1));

            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[1]));
            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[2]));
            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[3]));

            //array with desired distances between the nodes for every edge
            double[] idealEdgeLength = new double[graph.Edges.Count];
            for (int i = 0; i < graph.Edges.Count; i++)
            {
                idealEdgeLength[i] = 100; //all edges should have this euclidean length
            }


            //create stress majorization class and set the desired distances on the edges
            StressMajorization majorizer = new StressMajorization();


            majorizer.Positions   = new List <Point>(graph.Nodes.Select(v => v.Center));
            majorizer.NodeVotings = new List <NodeVoting>(graph.Nodes.Count);

            // initialize for every node an empty block
            for (int i = 0; i < graph.Nodes.Count; i++)
            {
                var nodeVote = new NodeVoting(i); //by default there is already a block with weighting 1
                //optional: add second block with different type of edges, e.g., with stronger weight
                //var secondBlock = new VoteBlock(new List<Vote>(), 100);
                //nodeVote.VotingBlocks.Add(secondBlock);
                //var block2=nodeVote.VotingBlocks[1]; //block could be accessed like this in a later stage

                majorizer.NodeVotings.Add(nodeVote);
            }


            // for every edge set the desired distances by setting votings among the two end nodes.
            Dictionary <Node, int> posDict = new Dictionary <Node, int>();

            for (int i = 0; i < graph.Nodes.Count; i++)
            {
                posDict[graph.Nodes[i]] = i;
            }

            var edges = graph.Edges.ToArray();

            for (int i = 0; i < graph.Edges.Count; i++)
            {
                var edge    = edges[i];
                int nodeId1 = posDict[edge.Source];
                int nodeId2 = posDict[edge.Target];

                double idealDistance = idealEdgeLength[i];
                double weight        = 1 / (idealDistance * idealDistance);
                var    voteFromNode1 = new Vote(nodeId1, idealDistance, weight); // vote from node1 for node2
                var    voteFromNode2 = new Vote(nodeId2, idealDistance, weight); // vote from node2 for node1

                // add vote of node1 to list of node2 (in first voting block)
                majorizer.NodeVotings[nodeId2].VotingBlocks[0].Votings.Add(voteFromNode1);
                // add vote of node2 to list of node1 (in first voting block)
                majorizer.NodeVotings[nodeId1].VotingBlocks[0].Votings.Add(voteFromNode2);
            }

            //used localized method to reduce stress
            majorizer.Settings = new StressMajorizationSettings();
            majorizer.Settings.SolvingMethod = SolvingMethod.Localized;

            List <Point> result = majorizer.IterateAll();

            for (int i = 0; i < result.Count; i++)
            {
                graph.Nodes[i].Center = result[i];
            }
// #if DEBUG && !SHARPKIT
//             LayoutAlgorithmSettings.ShowGraph(graph);
// #endif
        }
 /// <summary>
 /// Constructor
 /// </summary>
 public ProximityOverlapRemoval(OverlapRemovalSettings settings, GeometryGraph graph)
 {
     Graph    = graph;
     Settings = settings;
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 public void RemoveOverlaps(GeometryGraph graph) {
     Graph = graph;
     RemoveOverlaps();
 }
 /// <summary>
 /// Computes distances between a selected set of nodes and all nodes.
 /// Pivot nodes are selected with maxmin strategy (first at random, later
 /// ones to maximize distances to all previously selected ones).
 /// </summary>
 /// <param name="graph">A graph.</param>
 /// <param name="directed">Whether shortest paths are directed.</param>
 /// <param name="pivotArray">Number of pivots.</param>
 public PivotDistances(GeometryGraph graph, bool directed, int[] pivotArray)
 {
     this.graph      = graph;
     this.directed   = directed;
     this.pivotArray = pivotArray;
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 public SweeplineNestedRingTester(GeometryGraph graph)
 {
     this.graph = graph;
 }
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="graph"></param>
 public ProximityOverlapRemoval(GeometryGraph graph) {
     Graph = graph;
     InitializeSettings();
 }
예제 #8
0
 /// <summary>
 /// Dijkstra algorithm. Computes graph-theoretic distances from a node to
 /// all other nodes in a graph with nonnegative edge lengths.
 /// The distance between a node and itself is 0; the distance between a pair of
 /// nodes for which no connecting path exists is Double.PositiveInfinity.
 /// </summary>
 /// <param name="graph">A graph.</param>
 /// <param name="source">The source node.</param>
 /// <param name="directed">Whether the graph is directed.</param>
 public SingleSourceDistances(GeometryGraph graph, Node source)
 {
     this.graph  = graph;
     this.source = source;
 }
        internal GeometryGraph Create()
        {
            var msaglGraph = new GeometryGraph();

            return(FillGraph(msaglGraph));
        }
예제 #10
0
 /// <summary>
 /// Recursively lay out the clusters of the given graph using the given settings.
 /// </summary>
 /// <param name="graph">The graph being operated on.</param>
 /// <param name="defaultSettings">Settings to use if none is provided for a particular cluster or its ancestors.</param>
 public InitialLayoutByCluster(GeometryGraph graph, LayoutAlgorithmSettings defaultSettings)
     : this(graph, anyCluster => defaultSettings)
 {
 }
예제 #11
0
 public InitialLayoutByCluster(GeometryGraph graph, Func <Cluster, LayoutAlgorithmSettings> clusterSettings)
     : this(graph, new[] { graph.RootCluster }, clusterSettings)
 {
 }
예제 #12
0
 private static void AddNode(string id, GeometryGraph graph, double w, double h)
 {
     graph.Nodes.Add(new Node(CreateCurve(w, h), id));
 }
예제 #13
0
        static internal GeometryGraph CreateAndLayoutGraph()
        {
            GeometryGraph graph = new GeometryGraph();

            double width  = 40;
            double height = 10;

            foreach (string id in "0 1 2 3 4 5 6 A B C D E F G a b c d e".Split(' '))
            {
                AddNode(id, graph, width, height);
            }

            graph.Edges.Add(new Edge(graph.FindNodeByUserData("A"), graph.FindNodeByUserData("B")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("A"), graph.FindNodeByUserData("C")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("A"), graph.FindNodeByUserData("D")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("D"), graph.FindNodeByUserData("E")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("B"), graph.FindNodeByUserData("E")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("D"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("0"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("1"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("2"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("3"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("4"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("5"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("6"), graph.FindNodeByUserData("F")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("a"), graph.FindNodeByUserData("b")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("b"), graph.FindNodeByUserData("c")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("c"), graph.FindNodeByUserData("d")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("d"), graph.FindNodeByUserData("e")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("A"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("B"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("C"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("D"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("E"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("F"), graph.FindNodeByUserData("a")));
            graph.Edges.Add(new Edge(graph.FindNodeByUserData("G"), graph.FindNodeByUserData("a")));

            var settings = new SugiyamaLayoutSettings();

            settings.Transformation = PlaneTransformation.Rotation(Math.PI / 2);
            settings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.Spline;
            var layout = new LayeredLayout(graph, settings);

            layout.Run();
            return(graph);
//            double w = 40;
//            double h = 10;
//            GeometryGraph graph = new GeometryGraph();
            //columns
//            var col0 = new[] { "a", "b", "c" };
//            var col1 = new[] { "d", "e", "f", "g" };
//            var col2 = new[] { "k", "l", "m", "n" };
//            var col3 = new[] { "w", "y", "z" };
//
//            var settings = new SugiyamaLayoutSettings();
//
//            foreach (var id in col0)
//                AddNode(id, graph, w, h);
//            foreach (var id in col1)
//                AddNode(id, graph, w, h);
//            foreach (var id in col2)
//                AddNode(id, graph, w, h);
//            foreach (var id in col3)
//                AddNode(id, graph, w, h);
//
            //pinning columns
//            settings.PinNodesToSameLayer(col0.Select(s=>graph.FindNodeByUserData(s)).ToArray());
//            settings.PinNodesToSameLayer(col1.Select(s => graph.FindNodeByUserData(s)).ToArray());
//            settings.PinNodesToSameLayer(col2.Select(s => graph.FindNodeByUserData(s)).ToArray());
//            settings.PinNodesToSameLayer(col3.Select(s => graph.FindNodeByUserData(s)).ToArray());
//
//            AddEdgesBetweenColumns(col0, col1, graph);
//            AddEdgesBetweenColumns(col1, col2, graph);
//            AddEdgesBetweenColumns(col2, col3, graph);
            //rotate layer to columns
            // graph.Transformation = PlaneTransformation.Rotation(Math.PI / 2);
//            settings.NodeSeparation = 5;
//            settings.LayerSeparation = 100;
//            var ll = new LayeredLayout(graph, settings);
//            ll.Run();
//            return graph;
        }
예제 #14
0
 internal void AddConnectedGeomGraph(GeometryGraph geomGraph)
 {
     _connectedComponents.Add(geomGraph);
 }
예제 #15
0
 private static void LayoutAndValidate(GeometryGraph graph, SugiyamaLayoutSettings settings, double nodeSeparation)
 {
     LayoutAndValidate(graph, settings, nodeSeparation, LayerDirection.TopToBottom);
 }
        /// <summary>
        /// create a geometry edge, the geometry source and target have to be set already
        /// </summary>
        /// <param name="drawingEdge"></param>
        /// <param name="msaglGraph"></param>
        /// <returns></returns>
        static Core.Layout.Edge CreateGeometryEdgeAndAddItToGeometryGraph(Edge drawingEdge, GeometryGraph msaglGraph)
        {
            var msaglEdge = CreateGeometryEdgeFromDrawingEdge(drawingEdge);

            msaglGraph.Edges.Add(msaglEdge);

            return(msaglEdge);
        }
예제 #17
0
 internal LgData(GeometryGraph mainGeomGraph)
 {
     this.mainGeomGraph = mainGeomGraph;
 }
예제 #18
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            try
            {
                //Extract the parameter data
                var floors   = new List <Line>();
                var walls    = new List <Line>();
                var ceilings = new List <Line>();

                var elecTargets = new List <Grasshopper.Kernel.Types.GH_Point>();
                var elecSource  = new Grasshopper.Kernel.Types.GH_Point();

                var floorMulti   = 0.0;
                var wallMulti    = 0.0;
                var ceilingMulti = 0.0;

                if (!DA.GetDataList(0, floors))
                {
                    return;
                }

                if (!DA.GetDataList(1, walls))
                {
                    return;
                }

                if (!DA.GetDataList(2, ceilings))
                {
                    return;
                }

                if (!DA.GetDataList(3, elecTargets))
                {
                    return;
                }

                if (!DA.GetData(4, ref elecSource))
                {
                    return;
                }

                if (!DA.GetData(5, ref floorMulti))
                {
                    return;
                }

                if (!DA.GetData(6, ref wallMulti))
                {
                    return;
                }

                if (!DA.GetData(7, ref ceilingMulti))
                {
                    return;
                }

                //build the graph along with a geometry -> edge/node map
                var graph = new GeometryGraph(floors, floorMulti, walls, wallMulti, ceilings, ceilingMulti);

                //get the corresponding node for the electric source
                if (!PathFindUtil.TryGetElectricNodes(DA, graph, elecSource, elecTargets, out var elecSourceNode, out var elecTargetNodes))
                {
                    DA.SetDataList(0, null);
                    DA.SetData(1, "Failed to find source on graph");
                }

                //find the shortest pats
                var res = graph.SolvePathFind(FindPathType.AStar, elecSourceNode, elecTargetNodes);

                //build the data tree with all of the paths
                var tree = PathFindUtil.BuildTree(res);

                DA.SetDataTree(0, tree);
                DA.SetData(1, "Success!");
            }
            catch (Exception x)
            {
                DA.SetDataList(0, null);
                DA.SetData(1, $"M: {x.Message} - S: {x.StackTrace}");
            }
        }
예제 #19
0
        /// <summary>
        /// For a given graph finds the obstacles for nodes and clusters, correctly parenting the obstacles
        /// according to the cluster hierarchy
        /// </summary>
        /// <param name="graph">graph with edges to route and nodes/clusters to route around</param>
        /// <returns>the set of obstacles with correct cluster hierarchy and ports</returns>
        public static IEnumerable <Shape> GetShapes(GeometryGraph graph)
        {
            var nodesToShapes    = new Dictionary <Node, Shape>();
            var interestingNodes = graph.Nodes.Where(n => !n.UnderCollapsedCluster()).ToArray();

            foreach (var v in interestingNodes)
            {
                nodesToShapes[v] = CreateShapeWithCenterPort(v);
            }
            foreach (var c in graph.RootCluster.AllClustersDepthFirst())
            {
                if (!c.IsCollapsed)
                {
                    foreach (var v in c.Nodes)
                    {
                        if (!nodesToShapes.ContainsKey(v))
                        {
                            nodesToShapes[v] = CreateShapeWithCenterPort(v);
                        }
                    }
                }


                if (c == graph.RootCluster)
                {
                    continue;
                }
                var parent = nodesToShapes[c] = CreateShapeWithClusterBoundaryPort(c);
                if (c.IsCollapsed)
                {
                    continue;
                }
                foreach (var v in c.Nodes)
                {
                    parent.AddChild(nodesToShapes[v]);
                }
                foreach (var d in c.Clusters)
                {
                    parent.AddChild(nodesToShapes[d]);
                }
            }

            foreach (var edge in graph.Edges)
            {
                Shape shape;
                if (nodesToShapes.TryGetValue(edge.Source, out shape))
                {
                    if (edge.SourcePort != null)
                    {
                        shape.Ports.Insert(edge.SourcePort);
                    }
                }
                if (nodesToShapes.TryGetValue(edge.Target, out shape))
                {
                    if (edge.TargetPort != null)
                    {
                        shape.Ports.Insert(edge.TargetPort);
                    }
                }
            }

            return(nodesToShapes.Values);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="geometryGraph"></param>
 public ObjectDragUndoRedoAction(GeometryGraph geometryGraph) : base(geometryGraph)
 {
 }
 /// <summary>
 /// This method can directly be called to resolve overlaps on a graph with a given node separationl.
 /// </summary>
 /// <param name="geometryGraph"></param>
 /// <param name="nodeSeparation"></param>
 public static void RemoveOverlaps(GeometryGraph geometryGraph, double nodeSeparation) {
     var prism = new ProximityOverlapRemoval(geometryGraph) {Settings = {NodeSeparation = nodeSeparation}};
     prism.RemoveOverlaps();
     
 }
예제 #22
0
 internal UndoRedoAction(GeometryGraph graphPar)
 {
     this.Graph = graphPar;
     this.graphBoundingBoxBefore = this.Graph.BoundingBox;
 }
예제 #23
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="zoomLevel"></param>
 /// <param name="geomGraph">needed only for statistics</param>
 internal LgLevel(int zoomLevel, GeometryGraph geomGraph)
 {
     _geomGraph = geomGraph;
     ZoomLevel  = zoomLevel;
 }
예제 #24
0
        /// <summary>
        /// Create the graph data structures.
        /// </summary>
        /// <param name="geometryGraph"></param>
        /// <param name="settings">The settings for the algorithm.</param>
        /// <param name="initialConstraintLevel">initialize at this constraint level</param>
        /// <param name="clusterSettings">settings by cluster</param>
        internal FastIncrementalLayout(GeometryGraph geometryGraph, FastIncrementalLayoutSettings settings,
                                       int initialConstraintLevel,
                                       Func <Cluster, LayoutAlgorithmSettings> clusterSettings)
        {
            graph                = geometryGraph;
            this.settings        = settings;
            this.clusterSettings = clusterSettings;
            int i = 0;
            ICollection <Node> allNodes = graph.Nodes;

            nodes = new FiNode[allNodes.Count];
            foreach (Node v in allNodes)
            {
                v.AlgorithmData = nodes[i] = new FiNode(i, v);
                i++;
            }

            clusterEdges.Clear();
            edges.Clear();

            foreach (Edge e in graph.Edges)
            {
                if (e.Source is Cluster || e.Target is Cluster)
                {
                    clusterEdges.Add(e);
                }
                else
                {
                    edges.Add(new FiEdge(e));
                }
                foreach (var l in e.Labels)
                {
                    l.InnerPoints = l.OuterPoints = null;
                }
            }
            SetLockNodeWeights();
            components = new List <FiNode[]>();
            if (!settings.InterComponentForces)
            {
                basicGraph = new BasicGraph <FiEdge>(edges, nodes.Length);
                foreach (var componentNodes in ConnectedComponentCalculator <FiEdge> .GetComponents(basicGraph))
                {
                    var vs = new FiNode[componentNodes.Count()];
                    int vi = 0;
                    foreach (int v in componentNodes)
                    {
                        vs[vi++] = nodes[v];
                    }

                    components.Add(vs);
                }
            }
            else // just one big component (regardless of actual edges)
            {
                components.Add(nodes);
            }
            horizontalSolver = new AxisSolver(true, nodes, new[] { geometryGraph.RootCluster }, settings.AvoidOverlaps,
                                              settings.MinConstraintLevel, clusterSettings)
            {
                OverlapRemovalParameters =
                    new OverlapRemovalParameters {
                    AllowDeferToVertical = true,
                    // use "ProportionalOverlap" mode only when iterative apply forces layout is being used.
                    // it is not necessary otherwise.
                    ConsiderProportionalOverlap = settings.ApplyForces
                }
            };
            verticalSolver = new AxisSolver(false, nodes, new[] { geometryGraph.RootCluster }, settings.AvoidOverlaps,
                                            settings.MinConstraintLevel, clusterSettings);

            SetupConstraints();
            geometryGraph.RootCluster.ComputeWeight();

            foreach (
                Cluster c in geometryGraph.RootCluster.AllClustersDepthFirst().Where(c => c.RectangularBoundary == null)
                )
            {
                c.RectangularBoundary = new RectangularClusterBoundary();
            }

            CurrentConstraintLevel = initialConstraintLevel;
        }
예제 #25
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="geomGraph"></param>
 public ConsistentAreaTester(GeometryGraph geomGraph)
 {
     this.geomGraph = geomGraph;
 }
예제 #26
0
 /// <summary>
 /// Constructs the multidimensional scaling algorithm.
 /// </summary>
 public MdsGraphLayout(MdsLayoutSettings settings, GeometryGraph geometryGraph)
 {
     this.settings = settings;
     graph         = geometryGraph;
 }
예제 #27
0
 /// <summary>
 /// saves the graph to a file
 /// </summary>
 public static void Write(GeometryGraph graph, string fileName)
 {
     Write(graph, null, fileName);
 }
예제 #28
0
파일: Program.cs 프로젝트: Caliper/MSAGL
        public static void MDS()
        {
            WriteMessage("Starting test...");

            WriteMessage("Create GeometryGraph");

            GeometryGraph graph = AbcdeGraph();

            //graph.Save("c:\\tmp\\saved.msagl");
            var settings = new MdsLayoutSettings();

            settings.RunInParallel = false;

            settings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.Rectilinear;

            LayoutHelpers.CalculateLayout(graph, settings, null);


            WriteMessage("Layout progressed");

            WriteMessage("");
            WriteMessage("Segments A->B");
            //OutputCurve(ab.Curve);

            WriteMessage("");
            WriteMessage("Segments B->C");
            //OutputCurve(bc.Curve);

            WriteMessage("");
            WriteMessage("Segments C->A");
            //OutputCurve(ca.Curve);

            foreach (var node in graph.Nodes)
            {
                WriteMessage(string.Format("{0}: {1} {2}", node.UserData, node.Center.X, node.Center.Y));
            }

            /*var canvas = HtmlContext.document.getElementById("drawing").As<HtmlCanvasElement>();
             * var ctx = canvas.getContext("2d").As<CanvasRenderingContext2D>();
             *
             * var canvasHeight = canvas.height;
             *
             * var bounds = calcBounds(graph.Nodes);
             *
             * var xScale = canvas.width / bounds.Width;
             * var yScale = canvas.height / bounds.Height;
             *
             * var xShift = -bounds.Left * xScale;
             * var yShift = -(canvas.height - bounds.Top) * yScale;
             *
             * WriteMessage(string.Format("Scaling : {0} {1}", xScale, yScale));
             * WriteMessage(string.Format("Shifting : {0} {1}", xShift, yShift));
             *
             * foreach (var msaglEdge in graph.Edges)
             * {
             *  DrawEdge(ctx, msaglEdge, xShift, yShift, xScale, yScale, canvasHeight);
             * }
             *
             * foreach (var msaglNode in graph.Nodes)
             * {
             *  DrawNode(ctx, msaglNode, xShift, yShift, xScale, yScale, canvasHeight);
             * }*/
        }
 /// <summary>
 ///     Constructor
 /// </summary>
 /// <param name="graph"></param>
 public ProximityOverlapRemoval(GeometryGraph graph)
 {
     Graph = graph;
     InitializeSettings();
 }
예제 #30
0
파일: Program.cs 프로젝트: Caliper/MSAGL
        public static void LayeredLayoutAbc()
        {
            double        w     = 30;
            double        h     = 20;
            GeometryGraph graph = new GeometryGraph();

            MSAGLNode a = new MSAGLNode(new Ellipse(w, h, new Point()), "a");
            MSAGLNode b = new MSAGLNode(CurveFactory.CreateRectangle(w, h, new Point()), "b");
            MSAGLNode c = new MSAGLNode(CurveFactory.CreateRectangle(w, h, new Point()), "c");

            graph.Nodes.Add(a);
            graph.Nodes.Add(b);
            graph.Nodes.Add(c);
            Edge ab = new Edge(a, b)
            {
                Length = 10
            };
            Edge bc = new Edge(b, c)
            {
                Length = 3
            };

            graph.Edges.Add(ab);
            graph.Edges.Add(bc);

            var settings = new SugiyamaLayoutSettings();

            LayoutHelpers.CalculateLayout(graph, settings, null);


            WriteMessage("Layout progressed");

            /*WriteMessage("");
             * WriteMessage("Segments A->B");
             * //OutputCurve(ab.Curve);
             *
             * WriteMessage("");
             * WriteMessage("Segments B->C");
             * //OutputCurve(bc.Curve);
             *
             * WriteMessage("");
             * WriteMessage("Segments C->A");
             * //OutputCurve(ca.Curve);
             *
             * foreach (var node in graph.Nodes)
             * {
             *  WriteMessage(string.Format("{0}: {1} {2}", node.UserData, node.Center.X, node.Center.Y));
             * }*/

            /*var canvas = HtmlContext.document.getElementById("drawing").As<HtmlCanvasElement>();
             * var ctx = canvas.getContext("2d").As<CanvasRenderingContext2D>();
             *
             * var canvasHeight = canvas.height;
             *
             * var bounds = calcBounds(graph.Nodes);
             *
             * var xScale = canvas.width / bounds.Width;
             * var yScale = canvas.height / bounds.Height;
             *
             * var xShift = -bounds.Left * xScale;
             * var yShift = -(canvas.height - bounds.Top) * yScale;
             *
             * WriteMessage(string.Format("Scaling : {0} {1}", xScale, yScale));
             * WriteMessage(string.Format("Shifting : {0} {1}", xShift, yShift));
             *
             * foreach (var msaglEdge in graph.Edges)
             * {
             *  DrawEdge(ctx, msaglEdge, xShift, yShift, xScale, yScale, canvasHeight);
             * }
             *
             * foreach (var msaglNode in graph.Nodes)
             * {
             *  DrawNode(ctx, msaglNode, xShift, yShift, xScale, yScale, canvasHeight);
             * }*/
        }
예제 #31
0
 private static void LayoutAndValidate(GeometryGraph graph, SugiyamaLayoutSettings settings, LayerDirection direction)
 {
     LayoutAndValidate(graph, settings, settings.NodeSeparation, settings.LayerSeparation, direction);
 }
예제 #32
0
        /// <summary>
        /// Find a point from the list of testCoords
        /// that is NOT a node in the edge for the list of searchCoords.
        /// </summary>
        /// <param name="testCoords"></param>
        /// <param name="searchRing"></param>
        /// <param name="graph"></param>
        /// <returns>The point found, or <c>null</c> if none found.</returns>
        public static Coordinate FindPointNotNode(Coordinate[] testCoords, LinearRing searchRing, GeometryGraph graph)
        {
            // find edge corresponding to searchRing.
            var searchEdge = graph.FindEdge(searchRing);
            // find a point in the testCoords which is not a node of the searchRing
            var eiList = searchEdge.EdgeIntersectionList;

            // somewhat inefficient - is there a better way? (Use a node map, for instance?)
            foreach (var pt in testCoords)
            {
                if (!eiList.IsIntersection(pt))
                {
                    return(pt);
                }
            }
            return(null);
        }
        /// <summary>
        /// Example on how to use Stress Majorization with a small graph and Localized method.
        /// </summary>
        public static void RunStressMajorizationExample() {

            //create a star graph where three nodes are connected to the center
            GeometryGraph graph = new GeometryGraph();
            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());
            graph.Nodes.Add(new Node());

            //set initial positions, e.g., random
            graph.Nodes[0].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(5, 5));
            graph.Nodes[1].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(7, 10));
            graph.Nodes[2].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(7, 2));
            graph.Nodes[3].BoundaryCurve = CurveFactory.CreateRectangle(20, 10, new Point(35, 1));

            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[1]));
            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[2]));
            graph.Edges.Add(new Edge(graph.Nodes[0], graph.Nodes[3]));

            //array with desired distances between the nodes for every edge
            double[] idealEdgeLength=new double[graph.Edges.Count];
            for (int i = 0; i < graph.Edges.Count; i++) {
                idealEdgeLength[i] = 100; //all edges should have this euclidean length
            }


            //create stress majorization class and set the desired distances on the edges
            StressMajorization majorizer = new StressMajorization();


            majorizer.Positions = new List<Point>(graph.Nodes.Select(v=>v.Center));
            majorizer.NodeVotings = new List<NodeVoting>(graph.Nodes.Count);

            // initialize for every node an empty block
            for (int i = 0; i < graph.Nodes.Count; i++) {
                var nodeVote = new NodeVoting(i); //by default there is already a block with weighting 1
                //optional: add second block with different type of edges, e.g., with stronger weight
                //var secondBlock = new VoteBlock(new List<Vote>(), 100);
                //nodeVote.VotingBlocks.Add(secondBlock);
                //var block2=nodeVote.VotingBlocks[1]; //block could be accessed like this in a later stage
                
                majorizer.NodeVotings.Add(nodeVote);
            }


            // for every edge set the desired distances by setting votings among the two end nodes.
            Dictionary<Node,int> posDict=new Dictionary<Node, int>();
            for (int i = 0; i < graph.Nodes.Count; i++) {
                posDict[graph.Nodes[i]] = i;
            }

            var edges = graph.Edges.ToArray();
            for (int i=0; i<graph.Edges.Count;i++) {
                var edge = edges[i];
                int nodeId1 = posDict[edge.Source];
                int nodeId2 = posDict[edge.Target];

                double idealDistance = idealEdgeLength[i];
                double weight = 1 / (idealDistance * idealDistance);
                var voteFromNode1 = new Vote(nodeId1, idealDistance, weight); // vote from node1 for node2
                var voteFromNode2 = new Vote(nodeId2, idealDistance, weight); // vote from node2 for node1
                
                // add vote of node1 to list of node2 (in first voting block)
                majorizer.NodeVotings[nodeId2].VotingBlocks[0].Votings.Add(voteFromNode1);
                // add vote of node2 to list of node1 (in first voting block)
                majorizer.NodeVotings[nodeId1].VotingBlocks[0].Votings.Add(voteFromNode2);
               

            }

            //used localized method to reduce stress
            majorizer.Settings=new StressMajorizationSettings();
            majorizer.Settings.SolvingMethod=SolvingMethod.Localized;

            List<Point> result = majorizer.IterateAll();

            for (int i = 0; i < result.Count; i++) {
                graph.Nodes[i].Center = result[i];
            }
#if DEBUG && !SILVERLIGHT && !SHARPKIT
            LayoutAlgorithmSettings.ShowGraph(graph);
#endif
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="geomGraph"></param>
 public ConnectedInteriorTester(GeometryGraph geomGraph)
 {
     _geomGraph = geomGraph;
 }