Force layout using forces instead of dx/dy #967

Closed
wants to merge 2 commits into
from

Conversation

2 participants

Hi Mike,

Happily been using your library for quite some time. I need to show you our web app 'scotty' one time, which uses some really nice technologies and visualizations. Currently I have it hosted internally, but I'm sure I can port-forward it for you.

Now the pull request. I noticed the amount of forces applied to the nodes was smaller on my machine compared with a laptop of a coworker. Also, during 'long' frames, I saw a change in the amount of force. I isolated it to the force layouter, which doesn't take framerate into account.

The commit I added to my repo:

  • Use forces instead of dx/dy to calculate next frame proportional to dt (delta-t)
  • Allow user to set function for extra calculation of force.
  • Drag force added to better simulate fluid environment in addition to friction. Allows simulation of air/water drag.

This creates problems with the examples which most likely need to be updated. Let me know what you think and I'll fix it somewhere next week.

With kind regards,

Edwin de Jong

Edwin de Jong added some commits Dec 16, 2012

Force layout didn't take framerate into account.
- Use forces instead of dx/dy to calculate next frame proportional
  to dt (delta-t)
- Allow user to set function for extra calculation of force.
- Drag force added to better simulate fluid environment in addition
  to friction. Allows simulation of air/water drag.
Improvements for multitouch devices. TouchId is zero in certain brows…
…ers, such as Chrome and can therefor not be used as a truthy value.
Owner

mbostock commented Jan 23, 2013

Hi Edwin,

Thanks for the pull request. Since there are multiple components to this request I will address them separately.

I'd rather not use a variable time step for the force simulation. In addition to being more complicated, it also means that the simulation will perform worse, albeit at the same rate, on slower machines. Since there is no expectation that the force layout be performed at the same rate across machines, it seems preferable that it perform with the same quality, or at least chose the simpler of the two approaches. In other words the force layout is not time-based but iteration-based, and on slower machines there will be fewer iterations per time interval.

As for user-defined forces, that is typically done by listening to tick events. For example, the collision detection example uses the tick event to apply a custom geometric constraint. There are more examples of custom forces in the gallery.

This same technique could be used to apply a custom drag force. I didn't look too closely at the exact type of drag force you implemented, but one subtle issue here is the stability of the forces. Forces that are derived from the particle’s velocity are typically much less stable when using position Verlet integration, since this type of integration has higher error in velocity (in favor of making it easier to apply geometric constraints).

Thanks,
Mike

@mbostock mbostock closed this Jan 23, 2013

Hi Mike,

I understand you are hesitating to change a core functionality of d3.
Your arguments make sense, but you might have misinterpreted the change.
The new implementation waits for a tick event, but calculates the
difference with the previous frame and applies the forces
proportionally. Therefor, the behaviour of the layout does not change
when the frame rate changes during rendering, giving a stable and
friendly appearance. On a slower machine, the layout will be less
precise, but will still feel identical to a fast machine. If we miss a
frame (e.g. because of a calculation), the simulation remains smooth.

Since the simulation is more true to real world physics, it is simpler
to understand and extend. Drag forces, for example, can only be
calculated correctly in relationship with the speed of the object.

The user-defined forces can be extended to allow for a component based
system for the force layout. E.g. the drag, friction, 'gravity', spring
and static forces could be implemented as a user-defined force. The
components would work together to deliver similar behaviour as your
implementation. This separation of concerns makes the code understandable.

I've tried the new implementation on relatively complex graphs,
containing hundreds of nodes and thousands of edges with a strong
centrality. The simulation is stable, unless the drag forces become very
high. This is easily circumvented by adding a cap on the drag force applied.

In any case, I feel you're missing an opportunity to extend the quality
of the force directed layout. Have you tried my implementation?

With kind regards,

Edwin de Jong

On 01/23/2013 08:13 PM, Mike Bostock wrote:

Hi Edwin,

Thanks for the pull request. Since there are multiple components to
this request I will address them separately.

I'd rather not use a variable time step for the force simulation. In
addition to being more complicated, it also means that the simulation
will perform worse, albeit at the same rate, on slower machines. Since
there is no expectation that the force layout be performed at the same
rate across machines, it seems preferable that it perform with the
same quality, or at least chose the simpler of the two approaches. In
other words the force layout is not time-based but iteration-based,
and on slower machines there will be fewer iterations per time interval.

As for user-defined forces, that is typically done by listening to
tick events. For example, the collision detection example
http://bl.ocks.org/3231298 uses the tick event to apply a custom
geometric constraint. There are more examples of custom forces in the
gallery.

This same technique could be used to apply a custom drag force. I
didn't look too closely at the exact type of drag force you
implemented, but one subtle issue here is the stability of the forces.
Forces that are derived from the particle’s velocity are typically
much less stable when using position Verlet integration, since this
type of integration has higher error in velocity (in favor of making
it easier to apply geometric constraints).

Thanks,
Mike


Reply to this email directly or view it on GitHub
mbostock#967 (comment).

Met vriendelijke groet,

Edwin de Jong

Topicus Onderwijs
Edwin de Jong
Edwin.de.Jong@topicus.nl mailto:Edwin.de.Jong@topicus.nl
+31 (0)6 4869 4147

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment