在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例常用C#方法 → A 2D/3D force directed graph algorithm in C#

A 2D/3D force directed graph algorithm in C#

常用C#方法

下载此实例
  • 开发语言:C#
  • 实例大小:0.07M
  • 下载次数:24
  • 浏览次数:190
  • 发布时间:2020-02-20
  • 实例类别:常用C#方法
  • 发 布 人:ww55555www
  • 文件格式:.zip
  • 所需积分:2
 相关标签: graph C# 2d 3d C#

实例介绍

【实例简介】

【实例截图】

from clipboard



from clipboard


【核心代码】


namespace EpForceDirectedGraphDemo

{
    public partial class ForceDirectedGraphForm : Form
    {
        const int width = 64;
        const int height = 32;
        Stopwatch stopwatch = new Stopwatch();

        Graphics paper;
        int panelTop;
        int panelBottom;
        int panelLeft;
        int panelRight;
         

        Dictionary<Node,GridBox> m_fdgBoxes;
        Dictionary<Edge, GridLine> m_fdgLines;
        Graph m_fdgGraph;
        ForceDirected2D m_fdgPhysics;
        Renderer m_fdgRenderer;
        

        System.Timers.Timer timer = new System.Timers.Timer(30);


        public ForceDirectedGraphForm()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
            this.Width = (width 1) * 20;
            this.Height = (height 1) * 20 100;
            this.MaximumSize = new Size(this.Width, this.Height);
            this.MaximizeBox = false;

            tbStiffness.Text = "81.76";
            tbRepulsion.Text = "40000.0";
            tbDamping.Text = "0.5";
            panelTop = 0;
            panelBottom = pDrawPanel.Size.Height;
            panelLeft = 0;
            panelRight = pDrawPanel.Size.Width;
            
            m_fdgBoxes = new Dictionary<Node, GridBox>();
            m_fdgLines = new Dictionary<Edge, GridLine>();
            m_fdgGraph = new Graph();
            m_fdgPhysics = new ForceDirected2D(m_fdgGraph,81.76f,40000.0f, 0.5f);
            m_fdgRenderer = new Renderer(this, m_fdgPhysics);
           

            pDrawPanel.Paint = new PaintEventHandler(DrawPanel_Paint);

            timer.Interval = 30;
            timer.Elapsed = new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Start();

        }

        private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            pDrawPanel.Invalidate();
        }
        private void DrawPanel_Paint(object sender, PaintEventArgs e)
        {
            stopwatch.Stop();
            var p = sender as Panel;
            paper = e.Graphics;

            GridBox box = new GridBox((panelRight - panelLeft) / 2, (panelBottom - panelTop) / 2, BoxType.Pinned);
            box.DrawBox(paper);

            m_fdgRenderer.Draw(0.05f); // TODO: Check Time

            stopwatch.Reset();
            stopwatch.Start();

           
        }

        private void ForceDirectedGraph_Paint(object sender, PaintEventArgs e)
        {
 
         
        }
        public Pair<int, int> GraphToScreen(FDGVector2 iPos)
        {
            Pair<int, int> retPair = new Pair<int, int>();
            retPair.first = (int)(iPos.x (((float)(panelRight - panelLeft)) / 2.0f));
            retPair.second = (int)(iPos.y (((float)(panelBottom - panelTop)) / 2.0f));
            return retPair;
        }

        public FDGVector2 ScreenToGraph(Pair<int, int> iScreenPos)
        {
            FDGVector2 retVec = new FDGVector2();
            retVec.x= ((float)iScreenPos.first)-(((float)(panelRight-panelLeft))/2.0f);
            retVec.y = ((float)iScreenPos.second) - (((float)(panelBottom - panelTop)) / 2.0f);
            return retVec;
        }

        public void DrawLine(Edge iEdge, AbstractVector iPosition1, AbstractVector iPosition2)
        {
            Pair<int, int> pos1 = GraphToScreen(iPosition1 as FDGVector2);
            Pair<int, int> pos2 = GraphToScreen(iPosition2 as FDGVector2);
            m_fdgLines[iEdge].Set(pos1.first, pos1.second, pos2.first, pos2.second);
            m_fdgLines[iEdge].DrawLine(paper);
            
        }

        public void DrawBox(Node iNode, AbstractVector iPosition)
        {
            Pair<int, int> pos = GraphToScreen(iPosition as FDGVector2);
            m_fdgBoxes[iNode].Set(pos.first, pos.second);
            m_fdgBoxes[iNode].DrawBox(paper);
        }

        private void btnChangeProperties_Click(object sender, EventArgs e)
        {
            float stiffNess = System.Convert.ToSingle(tbStiffness.Text);
            m_fdgPhysics.Stiffness = stiffNess;
            float repulsion = System.Convert.ToSingle(tbRepulsion.Text);
            m_fdgPhysics.Repulsion = repulsion;
            float damping = System.Convert.ToSingle(tbDamping.Text);
            m_fdgPhysics.Damping = damping;
        }

        private bool addNode(string nodeName)
        {
            nodeName = nodeName.Trim();
            if (m_fdgGraph.GetNode(tbNodeName.Text) != null)
            {
                return false;
            }
            Node newNode = m_fdgGraph.CreateNode(nodeName);
            m_fdgBoxes[newNode] = new GridBox(0, 0, BoxType.Normal);

            cbbFromNode.Items.Add(nodeName);
            cbbToNode.Items.Add(nodeName);
            lbNode.Items.Add(nodeName);
            return true;
        }
        private void btnAddNode_Click(object sender, EventArgs e)
        {
            tbNodeName.Text=tbNodeName.Text.Trim();
            if (tbNodeName.Text == "")
            {
                MessageBox.Show("Please type in the node name to insert!");
                return;
            }
            if (!addNode(tbNodeName.Text))
            {
                MessageBox.Show("Node already exists in the graph!");
                return;
            }
        }
        private bool addEdge(string nodeName1, string nodeName2)
        {
            nodeName1 = nodeName1.Trim();
            nodeName2 = nodeName2.Trim();
            if (nodeName1 == nodeName2)
            {
                return false;
            }
            Node node1 = m_fdgGraph.GetNode(nodeName1);
            Node node2 = m_fdgGraph.GetNode(nodeName2);
            EdgeData data = new EdgeData();

            string label = nodeName1 "-" nodeName2;
            data.label = label;
            data.length = 60.0f;

            Edge newEdge = m_fdgGraph.CreateEdge(node1, node2, data);
            m_fdgLines[newEdge] = new GridLine(0, 0, 0, 0);

            lbEdge.Items.Add(label);
            return true;
        }
        private void btnAddEdge_Click(object sender, EventArgs e)
        {
            string nodeName1 = cbbFromNode.Text;
            string nodeName2 = cbbToNode.Text;
            if (!addEdge(nodeName1,  nodeName2))
            {
                MessageBox.Show("Edge cannot be connected to same node!");
                return;
            }
        }

        private void btnRemoveNode_Click(object sender, EventArgs e)
        {
            if (lbNode.SelectedIndex != -1)
            {
                int selectedIdx = lbNode.SelectedIndex;
                string nodeName=(string)lbNode.SelectedItem;
                Node removeNode=m_fdgGraph.GetNode(nodeName);

                m_fdgBoxes.Remove(removeNode);
                List<Edge> edgeList = m_fdgGraph.GetEdges(removeNode);
                foreach(Edge edge in edgeList)
                {
                    m_fdgLines.Remove(edge);
                    int edgeIndex=lbEdge.FindString(edge.Data.label);
                    lbEdge.Items.RemoveAt(edgeIndex);
                }
                m_fdgGraph.RemoveNode(removeNode);


                cbbFromNode.Items.RemoveAt(lbNode.SelectedIndex);
                cbbToNode.Items.RemoveAt(lbNode.SelectedIndex);

                lbNode.Items.RemoveAt(lbNode.SelectedIndex);
                if (selectedIdx != 0)
                    lbNode.SelectedIndex = selectedIdx-1;
                lbNode.Focus();
            }
            else
            {
                MessageBox.Show("Please select a node to remove!");
            }
        }

        private void btnRemoveEdge_Click(object sender, EventArgs e)
        {
            if (lbEdge.SelectedIndex != -1)
            {
                int selectedIdx = lbEdge.SelectedIndex;
                string edgeName = (string)lbEdge.SelectedItem;
                Edge removeEdge= m_fdgGraph.GetEdge(edgeName);
                m_fdgLines.Remove(removeEdge);
                m_fdgGraph.RemoveEdge(removeEdge);
                lbEdge.Items.RemoveAt(lbEdge.SelectedIndex);
                if (selectedIdx != 0)
                {
                    lbEdge.SelectedIndex = selectedIdx - 1;
                }
                lbEdge.Focus();
            }
            else
            {
                MessageBox.Show("Please select an edge to remove!");
            }
        }

        Node clickedNode;
        GridBox clickedGrid;
        private void pDrawPanel_MouseDown(object sender, MouseEventArgs e)
        {
            foreach (KeyValuePair<Node, GridBox> keyPair in m_fdgBoxes)
            {
                if(keyPair.Value.boxRec.IntersectsWith(new Rectangle(e.Location,new Size(1,1))))
                {
                    clickedNode = keyPair.Key;
                    clickedGrid = keyPair.Value;
                    clickedGrid.boxType = BoxType.Pinned;
                }
            }
        }

        private void pDrawPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (clickedNode != null)
            {

                FDGVector2 vec = ScreenToGraph(new Pair<int, int>(e.Location.X, e.Location.Y));
                clickedNode.Pinned = true;
                m_fdgPhysics.GetPoint(clickedNode).position = vec;
            }
            else
            {
                foreach (KeyValuePair<Node, GridBox> keyPair in m_fdgBoxes)
                {
                    if(keyPair.Value.boxRec.IntersectsWith(new Rectangle(e.Location,new Size(1,1))))
                    {
                        keyPair.Value.boxType = BoxType.Pinned;
                    }
                    else
                    {
                        keyPair.Value.boxType = BoxType.Normal;
                    }
                }

            }
        }

        private void pDrawPanel_MouseUp(object sender, MouseEventArgs e)
        {
            if (clickedNode != null)
            {
                clickedGrid.boxType = BoxType.Normal;
                clickedNode.Pinned = false;
                clickedNode = null;
                clickedGrid = null;
            }
        }

        private void tbNodeName_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnAddNode_Click(sender, e);
                tbNodeName.Focus();
            }
        }

        private void tbStiffness_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnChangeProperties_Click(sender, e);
                tbStiffness.Focus();
            }
        }

        private void tbRepulsion_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnChangeProperties_Click(sender, e);
                tbRepulsion.Focus();
            }
        }

        private void tbDamping_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnChangeProperties_Click(sender, e);
                tbDamping.Focus();
            }
        }

        
        private void btnLoad_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            DialogResult result = fileDialog.ShowDialog(); // Show the dialog.
            if (result == DialogResult.OK) // Test result.
            {
                string file = fileDialog.FileName;
                try
                {
                    string text = File.ReadAllText(file);
                    Int32 size = text.Length;

                    StringReader mapXML = new StringReader(text);
                    XmlTextReader xmlReader = new XmlTextReader(mapXML);
                    while (xmlReader.Read())
                    {
                        switch (xmlReader.NodeType)
                        {
                            case XmlNodeType.Element: // The node is an Element.
                                if (xmlReader.Name == "Node")
                                {
                                    loadNode(xmlReader);
                                }
                                else if (xmlReader.Name == "Edge")
                                {
                                    loadEdge(xmlReader);
                                }
                                break;

                            case XmlNodeType.Text: //Display the text in each element.
                                break;
                            case XmlNodeType.EndElement: //Display end of element.
                                break;
                        }
                    }
                }
                catch (IOException)
                {
                }
            }


        }

        private void loadNode(XmlTextReader iXmlReader)
        {
            while (iXmlReader.MoveToNextAttribute()) // Read attributes.
            {
                if (iXmlReader.Name == "nodeName")
                    addNode(iXmlReader.Value);
            }
        }
        private void loadEdge(XmlTextReader iXmlReader)
        {
            string nodeName1 = null;
            string nodeName2 = null;
            while (iXmlReader.MoveToNextAttribute()) // Read attributes.
            {
                if (iXmlReader.Name == "nodeName1")
                    nodeName1=iXmlReader.Value;
                if (iXmlReader.Name == "nodeName2")
                    nodeName2 = iXmlReader.Value;
            }
            addEdge(nodeName1, nodeName2);
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            m_fdgPhysics.Clear();
            m_fdgGraph.Clear();
            m_fdgBoxes.Clear();
            m_fdgLines.Clear();
            lbEdge.Items.Clear();
            lbNode.Items.Clear();
            cbbFromNode.Items.Clear();
            cbbToNode.Items.Clear();
        }
    }
}



标签: graph C# 2d 3d C#

实例下载地址

A 2D/3D force directed graph algorithm in C#

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警