Math 麦克的d3js集群部队布局图IV区块
我是d3js的新手,我才刚刚开始 我正在尝试Mike在他的一个模块中编写的集群布局示例。 我用我的代码让它在我的机器上工作,但我真的不喜欢盲目地复制代码而不理解它 然而,我很难理解“集群”和“碰撞”函数背后的数学,以及它们是如何工作的Math 麦克的d3js集群部队布局图IV区块,math,d3.js,visualization,data-visualization,Math,D3.js,Visualization,Data Visualization,我是d3js的新手,我才刚刚开始 我正在尝试Mike在他的一个模块中编写的集群布局示例。 我用我的代码让它在我的机器上工作,但我真的不喜欢盲目地复制代码而不理解它 然而,我很难理解“集群”和“碰撞”函数背后的数学,以及它们是如何工作的 谁能解释一下吗?谢谢你的帮助 让我们看看每种方法,我会尽我所能对其进行评论 簇 首先,呼叫方: function tick(e) { node .each(cluster(10 * e.alpha * e.alpha)) //for each no
谁能解释一下吗?谢谢你的帮助 让我们看看每种方法,我会尽我所能对其进行评论 簇 首先,呼叫方:
function tick(e) {
node
.each(cluster(10 * e.alpha * e.alpha)) //for each node on each tick call function returned by cluster function
//pass in alpha cooling parameter to collide
...
我不会在这里重复关于滴答事件如何工作的解释。问题很清楚
职能:
// returns a closure wrapping the cooling
// alpha (so it can be used for every node on the tick)
function cluster(alpha) {
return function(d) { // d here is the datum on the node
var cluster = clusters[d.cluster]; // clusters is a hash-map, the key is an index of the 10 clusters, the value is an object where d.cluster is the center node in that cluster
if (cluster === d) return; // if we are on the center node, do nothing
var x = d.x - cluster.x, // distance on x of node to center node
y = d.y - cluster.y, // distance on y of node to center node
l = Math.sqrt(x * x + y * y), // distance of node to center node (Pythagorean theorem)
r = d.radius + cluster.radius; // radius of node, plus radius of center node (the center node is always the largest one in the cluster)
if (l != r) { // if the node is not adjacent to the center node
l = (l - r) / l * alpha; //find a length that is slightly closer, this provides the illusion of it moving towards the center on each tick
d.x -= x *= l; // move node closer to center node
d.y -= y *= l;
cluster.x += x; // move center node closer to node
cluster.y += y;
}
};
}
碰撞
碰撞函数有点复杂。在我们深入研究它之前,您需要了解什么是四叉树以及Bostock为什么要使用它。如果您想确定两个元素是否冲突,那么简单的算法将是循环外部和内部元素,将每个元素与其他元素进行比较。当然,这在计算上是昂贵的,尤其是在每一个刻度上。这就是四叉树试图解决的问题:
四叉树递归地将二维空间划分为正方形,将每个正方形划分为四个大小相等的正方形。每个不同的点存在于唯一的叶节点中;重合点由链接列表表示。四叉树可以加速各种空间操作,例如用于计算多体力、碰撞检测和搜索附近点的Barnes–Hut近似
这是什么意思?首先,看看这个。用我自己简化的话来说,它的意思是:取一个二维空间,把它分成四个象限。如果任何象限包含4个或更少节点,则停止。如果象限包含四个以上的节点,请将其再次划分为四个象限。重复此操作,直到每个象限/子象限包含4个或更少的节点。现在,当我们寻找碰撞时,我们的内部循环不再循环节点,而是循环象限。如果象限没有碰撞,则移动到下一个象限。这是一个很大的优化
现在进入代码:
// returns a closure wrapping the cooling
// alpha (so it can be used for every node on the tick)
// and the quadtree
function collide(alpha) {
// create quadtree from our nodes
var quadtree = d3.geom.quadtree(nodes);
return function(d) { // d is the datum on the node
var r = d.radius + maxRadius + Math.max(padding, clusterPadding), // r is the radius of the node circle plus padding
nx1 = d.x - r, // nx1, nx2, ny1, ny2 are the bounds of collision detection on the node
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) { // visit each quadrant
if (quad.point && (quad.point !== d)) { // if the quadrant is a point (a node and not a sub-quadrant) and that point is not our current node
var x = d.x - quad.point.x, // distance on x of node to quad node
y = d.y - quad.point.y, // distance on y of node to quad node
l = Math.sqrt(x * x + y * y), // distance of node to quad node (Pythagorean theorem)
r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding); // radius of node in quadrant
if (l < r) { // if there is a collision
l = (l - r) / l * alpha; // re-position nodes
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
// This is important, it determines if the quadrant intersects
// with the node. If it does not, it returns false
// and we no longer visit and sub-quadrants or nodes
// in our quadrant, if true it descends into it
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
嘿谢谢它确实有用。如果可能,请为collide提供相同的。