-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
forceCollide
ignores fixed positions
#213
Comments
Not sure if this is a bug or works as intended—in any case, forceCollide doesn't check if the nodes are fixed or not, see Line 53 in 475ec96
Maybe try to change some parameters, by making the collision force slower, and solving in many more ticks:
|
It looks good for this demo, but I think I can't use it in my project. Because I call collision resolution simulation on every zoom event and 1000 iterations on each such event call is too much and laggy. Do you have any ideas how can I patch |
You'd need to make two additional tests, I think:
|
@Fil It is a bit more complicated You can have a fixed X or fixed Y or both. The other forces of the simulation change the Lines 36 to 37 in c3e73cf
Thus the moving nodes collide to a wrong circumference of the fixed node. The construction of the Lines 5 to 11 in c3e73cf
to place the node in the QuadTree. It is the wrong position for (partial) fixed nodes. So some tests may fail and a collision is not checked. In the Line 45 in c3e73cf
can be moveable or (partially) fixed. If both are XY-fixed do nothing |
@belukha The 2 empty spaces are caused by the "collision" of the 2 fixed nodes. they get a Lines 53 to 56 in c3e73cf
All the other nodes see a shadow version Lines 46 to 47 in c3e73cf
I have created pull request #225 The result is like: I used the code from You can create your own In the HTML use the following code: function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min); // The maximum is exclusive and the minimum is inclusive
}
var svg = d3.select("#svganchor")
.append("svg")
.attr("width", 1000)
.attr("height", 1000);
var data = [];
data.push({ x: 145, y: 145, fx: 145, fy: 145, r: 40, color: "blue" });
data.push({ x: 155, y: 155, fx: 155, fy: 155, r: 40, color: "green" });
for (let i = 0; i < 80; i++) {
data.push({ x: getRandomInt(0, 400), y: getRandomInt(0, 400), r: 10, color: "red" });
}
var simulation = d3.forceSimulation(data)
.force("collide", d3.forceCollide(d => d.r).strength(1).iterations(10))
.force("x", d3.forceX(150))
.force("y", d3.forceY(150));
var nodes = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("r", d => d.r)
.attr("fill", 'transparent')
.style("stroke", d => d.color);
simulation.on("tick", tick);
function tick() {
nodes
.attr("cx", function(d) { return d.x })
.attr("cy", function(d) { return d.y });
} |
I try to force circles to the point, and resolve collisions. But if some of these circles have fixed position, other circles behave like there're no circles with fixed positions.
demo: https://codesandbox.io/s/d3-forces-collide-ignore-fixed-position-w2qbkg?file=/src/index.ts
The text was updated successfully, but these errors were encountered: