public static void RunGraph(Program.Args args)
    {
        SqliteInput input = new(args.DbPath);
        Dictionary <int, DbNode> nodes = input.DeSerialize();

        ForceDirectedGraph forceDirectedGraph = new(args.RepulsiveForce, args.SpringForce);

        Dictionary <int, ForceDirectedGraph.Node> fdgNodes = new Dictionary <int, ForceDirectedGraph.Node>();

        foreach ((int key, DbNode dbNode) in nodes)
        {
            ForceDirectedGraph.Node newNode = forceDirectedGraph.AddNodeToGraph((uint)key);
            newNode.Position = dbNode.Position;
            fdgNodes.Add(key, newNode);
        }

        foreach ((int key, DbNode dbNode) in nodes)
        {
            fdgNodes.TryGetValue(key, out ForceDirectedGraph.Node nodeA);
            foreach (int dependencyKey in dbNode.edgeIds)
            {
                fdgNodes.TryGetValue(dependencyKey, out ForceDirectedGraph.Node nodeB);
                nodeA?.MyEdges.Add((uint)dependencyKey);
                nodeB?.MyEdges.Add((uint)key);
            }
        }

        Vector3[] results = forceDirectedGraph.RunGraph(args.Iterations);

        Console.WriteLine($"Writing to {args.DbPath}");

        SqliteOutput output = new(args.DbPath);

        output.Serialize(results);
    }
Beispiel #2
0
        /// <summary>
        /// Adds the specified Node to this Diagram.
        /// </summary>
        /// <param name="node">The Node to add to the diagram.</param>
        /// <returns>True if the node was added, false if the node is already on this Diagram.</returns>
        public bool AddNode(Node node)
        {
            if (node == null) throw new ArgumentNullException("node");

            if (!mNodes.Contains(node))
            {
                // add node, associate with diagram, then add all connected nodes
                mNodes.Add(node);
                node.Diagram = this;

                foreach (Node child in node.Connections)
                {
                    AddNode(child);
                }

                return true;
            }
            else
            {
                return false;
            }
        }
Beispiel #3
0
 /// <summary>
 /// Draws a connector between this node and the specified child node using GDI+. 
 /// The source and destination coordinates (relative to the Graphics surface) are also specified.
 /// </summary>
 /// <param name="graphics">GDI+ Graphics surface.</param>
 /// <param name="from">Source coodinate.</param>
 /// <param name="to">Destination coordinate.</param>
 /// <param name="other">The other node.</param>
 public virtual void DrawConnector(Graphics graphics, Point from, Point to, Node other)
 {
     graphics.DrawLine(Pens.Gray, surface.SurfaceOffsetAdjust(from), surface.SurfaceOffsetAdjust(to));
 }
Beispiel #4
0
 /// <summary>
 /// Removes any connection between this node and the specified node.
 /// </summary>
 /// <param name="other">The other node whose connection is to be removed.</param>
 /// <returns>True if a connection existed.</returns>
 public bool Disconnect(Node other)
 {
     bool c = this.mConnections.Remove(other);
     bool p = other.mConnections.Remove(this);
     return c || p;
 }
Beispiel #5
0
 /// <summary>
 /// Connects this node to the specified parent node.
 /// </summary>
 /// <param name="parent">The node to connect to this node.</param>
 /// <returns>True if the other node was connected to this node.</returns>
 public bool AddParent(Node parent)
 {
     if (parent == null) throw new ArgumentNullException("parent");
     return parent.AddChild(this);
 }
Beispiel #6
0
 /// <summary>
 /// Connects the specified child node to this node.
 /// </summary>
 /// <param name="child">The child node to add.</param>
 /// <returns>True if the node was connected to this node.</returns>
 public bool AddChild(Node child)
 {
     if (child == null) throw new ArgumentNullException("child");
     if ((child != this) && !this.mConnections.Contains(child))
     {
         child.Diagram = this.Diagram;
         this.mConnections.Add(child);
         return true;
     }
     else
     {
         return false;
     }
 }
        /// <summary>
        /// Adds the specified Node to this Diagram.
        /// </summary>
        /// <param name="node">The Node to add to the diagram.</param>
        /// <returns>True if the node was added, false if the node is already on this Diagram.</returns>
        public bool AddNode(Node node)
        {
            bool ret = false;

            if (node == null) throw new ArgumentNullException("node");

            if (!nodes.Contains(node))
            {
                // add node, associate with diagram, then add all connected nodes
                nodes.Add(node);
                node.Diagram = this;
                layout.Add(new NodeLayoutInfo(node, new Vector(), node.Location));

                foreach (Node child in node.Connections)
                {
                    AddNode(child);
                }

                ret = true;
            }

            return ret;
        }
            public Vector Velocity; // the node's current velocity, expressed in vector form

            #endregion Fields

            #region Constructors

            /// <summary>
            /// Initialises a new instance of the Diagram.NodeLayoutInfo class, using the specified parameters.
            /// </summary>
            /// <param name="node"></param>
            /// <param name="velocity"></param>
            /// <param name="nextPosition"></param>
            public NodeLayoutInfo(Node node, Vector velocity, PointF nextPosition)
            {
                Node = node;
                Velocity = velocity;
                NextPosition = nextPosition;
            }
        /// <summary>
        /// Calculates the repulsion force between any two nodes in the diagram space.
        /// </summary>
        /// <param name="x">The node that the force is acting on.</param>
        /// <param name="y">The node creating the force.</param>
        /// <returns>A Vector representing the repulsion force.</returns>
        private Vector CalcRepulsionForce(Node x, Node y)
        {
            double proximity = Math.Max(CalcDistance(x.Location, y.Location), 1);

            // Coulomb's Law: F = k(Qq/r^2)
            double force = -(REPULSION_CONSTANT / Math.Pow(proximity, 2));
            double angle = GetBearingAngle(x.Location, y.Location);

            return new Vector(force, angle);
        }
Beispiel #10
0
        /// <summary>
        /// Calculates the attraction force between two connected nodes, using the specified spring length.
        /// </summary>
        /// <param name="x">The node that the force is acting on.</param>
        /// <param name="y">The node creating the force.</param>
        /// <param name="springLength">The length of the spring, in pixels.</param>
        /// <returns>A Vector representing the attraction force.</returns>
        private Vector CalcAttractionForce(Node x, Node y, double springLength)
        {
            double proximity = Math.Max(CalcDistance(x.Location, y.Location), 1);

            // Hooke's Law: F = -kx
            double force = ATTRACTION_CONSTANT * Math.Max(proximity - springLength, 0);
            double angle = GetBearingAngle(x.Location, y.Location);

            return new Vector(force, angle);
        }
Beispiel #11
0
        /// <summary>
        /// Removes the specified node from the diagram. Any connected nodes will remain on the diagram.
        /// </summary>
        /// <param name="node">The node to remove from the diagram.</param>
        /// <returns>True if the node belonged to the diagram.</returns>
        public bool RemoveNode(Node node)
        {
            bool ret;

            // Disconnect this node from other nodes.

            foreach (Node other in nodes)
            {
                if ((other != node) && other.Connections.Contains(node))
                {
                    other.Disconnect(node);
                }
            }

            ret = nodes.Remove(node);
            layout.Remove(layout.Single(n => n.Node == node));

            return ret;
        }
Beispiel #12
0
 /// <summary>
 /// Determines whether the diagram contains the specified node.
 /// </summary>
 /// <param name="node">The node to test.</param>
 /// <returns>True if the diagram contains the node.</returns>
 public bool ContainsNode(Node node)
 {
     return nodes.Contains(node);
 }
Beispiel #13
0
 /// <summary>
 /// Removes the specified node from the diagram. Any connected nodes will remain on the diagram.
 /// </summary>
 /// <param name="node">The node to remove from the diagram.</param>
 /// <returns>True if the node belonged to the diagram.</returns>
 public bool RemoveNode(Node node)
 {
     node.Diagram = null;
     foreach (Node other in mNodes)
     {
         if ((other != node) && other.Connections.Contains(node)) other.Disconnect(node);
     }
     return mNodes.Remove(node);
 }
Beispiel #14
0
 /// <summary>
 /// Draws a connector between this node and the specified child node using GDI+. 
 /// The source and destination coordinates (relative to the Graphics surface) are also specified.
 /// </summary>
 /// <param name="graphics">GDI+ Graphics surface.</param>
 /// <param name="from">Source coodinate.</param>
 /// <param name="to">Destination coordinate.</param>
 /// <param name="other">The other node.</param>
 public virtual void DrawConnector(Graphics graphics, PointF from, PointF to, Node other)
 {
     graphics.DrawLine(Pens.Gray, from, to);
 }