Enhance Collision to handle shapes other than circles #38

Closed
zookini opened this Issue Jun 30, 2016 · 8 comments

Projects

None yet

5 participants

@zookini
zookini commented Jun 30, 2016

I currently use D3 v3 force layout with custom collision detection to prevent overlapping of text. Instead of using circle radius to prevent overlaps, I use rectangle width/height (derived from getBBox()) as this suits text better. Can we support rectangles in D4's Collision and possibly other shapes?

@mbostock
Member

Implementing a rectangular collision force is relatively straightforward. I wouldn’t overload d3.forceCollide by putting it there, but you could implement your own custom force to do it. Here’s an example in 3.x:

http://bl.ocks.org/mbostock/4055889

@Nesvet
Nesvet commented Jul 14, 2016

That's much-needed, Mike! And would be great if it comes to real! 👍

@gravitypersists

I'm having trouble understanding how I am supposed to update nodes from within a callback. I'm assuming there's some async behavior in there.

see: https://tonicdev.com/579956eeedc3e41200aac566/579956eeedc3e41200aac567

@mbostock
Member

@gravitypersists Please read the documentation for simulation.tick, which says:

This method does not dispatch events; events are only dispatched by the internal timer when the simulation is started automatically upon creation or by calling simulation.restart.

So in your example your tick event listener is not invoked until after the result is displayed to the console (assuming that tonic even continues to execute your code).

If you want to fix a node’s y-position to zero, set node.fy = 0 and see the documentation for simulation.nodes. (Note that you don’t have to re-set simulation.nodes after setting node.fy; that’s typically only done when you add or remove nodes from the simulation, not when you modify nodes’ properties.)

If you want to apply a custom force for every tick of the simulation, register a custom force using simulation.force instead of listening for tick events. Unlike in v3, tick events in v4 are intended for rendering the simulation interactively, not for affecting the result of the simulation.

If you want further assistance, please use Stack Overflow tag d3.js or the d3-js Google group to ask for help. This issue is intended to be a discussion around collision detection, not debugging your code. Thank you for your understanding!

@gravitypersists
gravitypersists commented Jul 28, 2016 edited

Unlike in v3, tick events in v4 are intended for rendering the simulation interactively, not for affecting the result of the simulation.

I see. Sorry if this seemed off-topic, only in retrospect do I realize that. I was trying to implement a collide callback for rects similar to the issue at hand and made the faulty assumption that tick callbacks could affect the simulation just as force callbacks could, and was naively using the two interoperably. Thanks for your help, and apologies for asking in the wrong place.

So this is not all for nothing, do you think it's appropriate to mention this in the documentation a bit more clearly? I'd be happy to try and fit it in, but only if you suggest so.

@mbostock mbostock added a commit that referenced this issue Jul 28, 2016
@mbostock mbostock Update README. Related #38. 8b6cffa
@mbostock
Member

I’ve updated the README in 8b6cffa.

@Fil
Fil commented Aug 12, 2016

I've been playing with this recently
http://bl.ocks.org/Fil/3f52274945a2be33a3f6bfd585ca949b

=> generic polygon detection is easily done with d3.polygonContains():
=> do a quadtree search before calling it, if you want to scale to thousands of points

@mbostock
Member
mbostock commented Oct 7, 2016

I feel this issue is addressed by the d3-bboxCollide plugin.

@mbostock mbostock closed this Oct 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment