我想将带有内容的正方形沿着带有force()和碰撞的圆展开,因此这些正方形和主圆不会相互重叠。
有什么想法怎么做?我应该使用链接来做到这一点吗?
这是一个小提琴http://jsfiddle.net/benderlio/usbq839m/3/
有时它可以很好地扩展正方形,但是大多数情况下,正方形会像img上那样移动。
var force = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody(1130))
// .force('link', d3.forceLink().links(links))
.on("tick", function () {
var k = this.alpha(),
kg = k * .02,
spaceAround = 0.04;
//console.log('', nodes);
nodes.forEach(function (a, i) {
...
});
svg.selectAll("rect")
.style("fill", function (d) {
return "#ccc"
})
.attr("x", function (d) {
return d.x - d.width / 2;
})
.attr("y", function (d) {
return d.y - d.height / 2;
});
svg.selectAll("line")
.attr("x2", function (d) {
return d.x;
})
.attr("y2", function (d) {
return d.y;
})
svg.selectAll("circle.end")
.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
})
});
谢谢。
UPD:
添加了一个主要的固定正方形,现在看起来更好。但是看起来我必须对“冲突顺序”做一些事情。正方形翻转。有什么想法如何解决?
最佳答案
我不知道解决此问题的一般方法,但是以下是一些更好的解决方法:
为矩形重力算法定义“目标点”时,使其不在圆的边界上,而是相距一定距离。
x = ((150 + radius) * Math.cos(angle)) + (width / 2) + offset; // Calculate the x position of the element.
y = ((150 + radius) * Math.sin(angle)) + (width / 2) + offset; // Calculate the y position of the element.
如果要使矩形不与圆碰撞,则需要自定义力。由于矩形和直线碰撞的精确公式并不简单,也许将矩形视为圆形就足够了,因此在
nodes.forEach(...)
之后添加:nodes.forEach(function(a) {
const diag = Math.sqrt(a.width ** 2 + a.height ** 2) / 2;
const rad = 150;
const [cx, cy] = [500, 500];
const [dx, dy] = [a.x - cx, a.y - cy];
const dist = Math.sqrt(dx ** 2 + dy ** 2);
const shift = Math.max(0, rad + diag - dist);
a.x += shift * dx / dist;
a.y += shift * dy / dist;
})
关于javascript - D3.js用力沿圆分布方格,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53515750/