Example #1
0
 /// <summary>
 /// 计算链接上结点速度
 /// </summary>
 public void forceLink()
 {
     alpha = Math.Round(alpha, 15);
     for (int k = 0; k < iterations; k++)
     {
         for (int i = 0; i < Links.Count; i++)
         {
             ForceLink link = Links[i];
             ForceNode source = link.source, target = link.target;
             double    x, y, l;
             //计算下一步的节点速度
             x = target.x + target.vx - source.x - source.vx;
             if (x == 0)     //此处有疑问
             {
                 x = jiggle();
             }
             y = target.y + target.vy - source.y - source.vy;
             if (y == 0)
             {
                 y = jiggle();
             }
             l  = Math.Sqrt(x * x + y * y);
             l  = (l - distancesLink[i]) / l * alpha * strengthsLink[i];
             x *= l;
             y *= l;
             double b = bias[i];
             target.vx -= x * b;
             target.vy -= y * b;
             b          = 1 - b;
             source.vx += x * b;
             source.vy += y * b;
         }
     }
 }
Example #2
0
        /// <summary>
        /// 返回与距离位置<x,y> 给定搜索半径最接近的节点
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="radius">半径</param>
        /// <returns></returns>
        ForceNode find(double x, double y, double radius)
        {
            ForceNode closest = null;

            if (radius == null)
            {
                radius = double.MaxValue;
            }
            else
            {
                radius *= radius;
            }
            for (int i = 0; i < Nodes.Count; i++)
            {
                var    node = Nodes[i];
                double dx   = x - node.x;
                double dy   = y - node.y;
                double d2   = dx * dx + dy * dy;
                if (d2 < radius)
                {
                    closest = node;
                    radius  = d2;
                }
            }
            if (closest != null)
            {
                return(closest);
            }
            else
            {
                return(null);
            }
        }
Example #3
0
        /// <summary>
        /// 析构函数
        /// </summary>
        /// <param name="filePath">Json文件地址</param>
        /// <param name="cWidth">绘图宽度</param>
        /// <param name="cHeight">绘图高度</param>
        public D3force(string filePath, double cWidth, double cHeight)
        {
            this.cWidth  = cWidth;
            this.cHeight = cHeight;
            StreamReader sr  = new StreamReader(filePath);
            string       str = sr.ReadToEnd();

            sr.Close();
            JObject json   = JObject.Parse(str);
            JArray  jnodes = (JArray)json["nodes"];
            int     i      = 0;

            foreach (var x in jnodes)
            {
                ForceNode node = new ForceNode
                {
                    group = Convert.ToInt32(x["group"]),
                    id    = x["id"].ToString(),
                    index = i,
                };
                Nodes.Add(node);
                i++;
            }
            JArray jlinks = (JArray)json["links"];
            int    j      = 0;

            foreach (var x in jlinks)
            {
                ForceLink link = new ForceLink
                {
                    index = j,
                    value = Convert.ToInt32(x["value"]),
                };
                string    source = x["source"].ToString();
                ForceNode sn     = Nodes.Find(s => s.id == source);
                if (sn != null)
                {
                    link.source = sn;
                }
                string    target = x["target"].ToString();
                ForceNode tn     = Nodes.Find(s => s.id == target);
                if (tn != null)
                {
                    link.target = tn;
                }
                Links.Add(link);
                j++;
            }

            //初始化结点
            initializeNodes();
            initializeForceLink();
            initializeManyBody();
        }
Example #4
0
 bool IsEqual(ForceNode source, ForceNode target)
 {
     if (source.group == target.group && source.id == target.id && source.index == target.index &&
         source.vx == target.vx && source.vy == target.vy && source.x == target.x && source.y == target.y)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #5
0
 public override void VisitForce(ForceNode node)
 {
     Visit(node.Selections);
 }
Example #6
0
 /// <summary>
 /// 获取节点
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public int index(ForceNode node)
 {
     return(node.index);
 }
Example #7
0
        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="x">节点x坐标</param>
        /// <param name="y">节点y坐标</param>
        /// <param name="d">节点数据</param>
        void add(double x, double y, ForceNode d)
        {
            if (x == null || y == null)
            {
                return;
            }
            var          node   = this._root;
            QuadtreeNode parent = node;
            var          leaf   = new QuadtreeNode
            {
                IsLeaf = true,
                data   = d
            };
            double x0 = this._x0, x1 = this._x1, y0 = this._y0, y1 = this._y1;
            double xm;      //四叉树当前区块x轴中点
            double ym;      //四叉树当前区块y轴中点
            double xp = .0; //数据结点x坐标
            double yp = .0; //数据结点y坐标
            int    right;
            int    bottom;
            int    i = 0;   //新结点在四叉树子节点列表中的位置
            int    j = 0;   //旧结点在四叉树子节点列表中的位置

            //如果根节点为空,初始化根节点为叶结点
            if (node.children == null && node.data == null)
            {
                this._root = leaf;
                return;
            }

            //找出新叶结点应在坐标,为其赋值
            while (node.children != null)    //当未查找至叶子节点时,不断计算
            {
                //判断叶新节点位于四叉树哪一个区块
                xm = (x0 + x1) / 2;
                if (x >= xm)
                {
                    x0    = xm;
                    right = 1;
                }
                else
                {
                    x1    = xm;
                    right = 0;
                }

                ym = (y0 + y1) / 2;
                if (y >= ym)
                {
                    y0     = ym;
                    bottom = 1;
                }
                else
                {
                    y1     = ym;
                    bottom = 0;
                }

                i = bottom << 1 | right;  //新结点在子节点中的排序

                //当前坐标节点为空时,添加叶结点
                parent = node;
                node   = node.children[i];
                if (node == null)
                {
                    parent.children[i] = leaf;
                    return;
                }
            }

            if (node != null && node.data != null)
            {
                xp = node.data.x;
                yp = node.data.y;
            }

            //判断新结点是否与已存在的节点的坐标完全一致
            if (x == xp && y == yp)
            {
                if (parent.children != null || parent.data != null)
                {
                    if (parent.children == null)
                    {
                        parent.children = new QuadtreeNode[4];
                    }
                    parent.children[i] = leaf;
                }
                else
                {
                    this._root = leaf;
                }
                return;
            }

            //切割叶结点,直到新旧节点并存
            var rootNode = parent;

            if (rootNode.data == null)
            {
                int dfe = 0;
            }
            do
            {
                if (parent.children != null)
                {
                    parent.children[i] = new QuadtreeNode();
                    parent             = parent.children[i];
                    parent.children    = new QuadtreeNode[4];
                }
                else
                {
                    this._root.children = new QuadtreeNode[4];
                    //parent = this._root;
                }


                //判断叶新节点位于四叉树哪一个区块
                xm = (x0 + x1) / 2;
                if (x >= xm)
                {
                    x0    = xm;
                    right = 1;
                }
                else
                {
                    x1    = xm;
                    right = 0;
                }

                ym = (y0 + y1) / 2;
                if (y >= ym)
                {
                    y0     = ym;
                    bottom = 1;
                }
                else
                {
                    y1     = ym;
                    bottom = 0;
                }

                i = bottom << 1 | right;  //新结点在子节点中的排序
                bool isOldY = yp >= ym;
                bool isOldX = xp >= xm;
                if (isOldY)
                {
                    if (isOldX)
                    {
                        j = 1 << 1 | 1;
                    }
                    else
                    {
                        j = 1 << 1 | 0;
                    }
                }
                else
                if (isOldX)
                {
                    j = 0 << 1 | 1;
                }
                else
                {
                    j = 0 << 1 | 0;
                }
            } while (i == j);
            //清除原有数据,并赋新值
            var oldNode = new QuadtreeNode
            {
                data   = node.data,
                IsLeaf = true
            };

            rootNode.data      = null;
            rootNode.IsLeaf    = false;
            parent.children[j] = oldNode;
            parent.children[i] = leaf;
        }