Skip to content
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

Inverse-square law in forceManyBody #95

Closed
vasturiano opened this issue May 30, 2017 · 11 comments
Closed

Inverse-square law in forceManyBody #95

vasturiano opened this issue May 30, 2017 · 11 comments
Labels

Comments

@vasturiano
Copy link
Contributor

If I'm reading the math correctly on forceManyBody():
https://github.com/d3/d3-force/blob/master/src/manyBody.js#L69
and
https://github.com/d3/d3-force/blob/master/src/manyBody.js#L87

It seems that the intensity of this force has an inverse linear relationship with the distance.

I.e. if d = distance between 2 nodes, x=x component of d, and l = d^2, then the velocity delta in x is set as vx += x * strength / l or the equivalent x/d * strength/d which makes the velocity delta to be strength/d.

Generally, these type of physical attraction forces, like gravity, electrostatic or magnetic tend to have an inverse-square relationship with the distance, so I was expecting strength/d^2.

Trying to understand whether the intention on this force was to model the mechanics of these physical forces or there was a different use case for which the linear relationship is acceptable or perhaps more suitable.

Thanks!

@mbostock
Copy link
Member

Yes, d3.forceManyBody is inverse-linear, not inverse-square. I double-checked your math and I also measured it empirically to confirm.

I agree that inverse-square is more common in nature. I’m not sure that switching to an inverse-square for this force would improve graph layout, however; it makes the force stronger locally and weaker globally. In practice this means that the strength of the force must be greatly increased, but it also makes it more “twitchy” in the first few ticks of the simulation.

@vasturiano
Copy link
Contributor Author

Ok, thanks for clearing that out.

I agree that changing it to inverse-square would break backwards compatibility as the current strength values would make it much weaker, specially for larger distances.

Would you consider adding a feature flag for this, say forceManyBody.useInverseSquare(), defaulting to false for backwards compatibility? To satisfy use cases when you want to use this force to model a physical behavior.

The alternative is to have a separate force plugin for this. I started hashing one out in https://github.com/vasturiano/d3-force-magnetic

But I'd prefer to have it in core d3-force. :)

@ddurschlag
Copy link

Couldn't this be turned into a function with a default value? e.g.:

var acceleration = function(value1, value2, distance, strength, alpha) {
return value1 * value1 * strength * alpha / distance;
}

...with standard accessor functions for changing it, same as strength etc.

Then you could just pass in an inverse-square function to get the desired behavior.

@vasturiano
Copy link
Contributor Author

@ddurschlag I find this a great idea! That would provide the most flexibility for specifying the interaction between any two nodes. It could default to reverse-linear, but by overriding it you could specify reverse-square but also other things like spring forces or even more abstract behaviors.

What I'm less sure is whether you need value1, value2. If these are supposed to represent the x/y coordinates of node1, node2, it would perhaps be better to leave it up to the framework to do the x/y trigonometry, and think of the acceleration as just a (dimensionless) vector.

@ddurschlag
Copy link

I most confess I was guessing a bit, as I find that code's use of single-letter variables and repeated names (quad.x, node.x, x, x1, and x2 are all separate values!) very hard to read. My assumption was that nodes could have inherent constants (charge, mass, etc.) that would be included in the equation. The obvious example of this is mass for gravity.

@vasturiano
Copy link
Contributor Author

The nodes' mass/charge can be set using the existing strength(node) accessor fn in a generic form (because the framework doesn't need to know the nature of the force, gravity or else, in order to do the computation). The nodes may have those constants but then one can simply direct the strength function to them.

Come to think of it, it seems unlikely one would need to also manipulate the influence of strength and alpha in the equation, because those already have their own accessor functions. The only part that is not exposed is how the distance actually contributes to the force. So, would it perhaps make sense to simplify that (new) accessor function to say .distanceRelationship(distance), which would default to d=>1/d for reverse-linear?

@ddurschlag
Copy link

My thinking was that the strength function is how you determine nodes' strengths (and mass function for mass, etc.). How those values (as well as other values like distance) combine for any two nodes (or aggregate within a quadrant for Barnes-Hut) seems like a separate calculation to me. While a distanceRelationship accessor would allow inverse linear and inverse quadratic distance factors, it would not, for example, allow strengths to vary between linear (s1 + s2, as in springs) and quadratic (s1*s2, as in gravity).

@Fil
Copy link
Member

Fil commented Jul 6, 2020

Maybe it's me being delirious, but "inverse-square is more common in nature" is because we're talking about 3D space.

You just need to figure gravitation as being enacted by the continuous emission of gravitons, instead of photons.

The gravitons are travelling from their source mass, at the speed of light c, in all directions… The gravitons emitted at time 0 will, at time t, be dispersed uniformly over a 2-sphere of radius R = c·t and area 4πR^2. The attraction between source and target mass results from the gravitons "intercepted" by the target, and that number decreases in proportion of the spherical angle of the target in the sphere. Thus, 1/R^2

However d3-force lives in 2D: the same quantity of gravitons emitted from a center are now dispersed over a circle (a 1-sphere), whose "area" is πR. If the motto was to obey "physics", in flatland it would still require gravitational forces to decrease as 1/R.

Related: #96

@ddurschlag
Copy link

I no longer use d3 (this issue being over three years old), so I write the following solely as a curiosity, rather than as input to the direction of the software.

I don't believe that explanation of gravity is applicable here, @Fil . For one, gravity of spherical objects is independent of their volume, so any volume-oriented argument is, to my mind, immediately suspect. After some brief googling, I also stumbled on the following paper: https://vixra.org/pdf/1704.0052v6.pdf . Its derivation does not appear to be dependent on the number of dimensions involved, but the number of work-quantities involved in the scale law's ratio.

One could argue, of course, that all the equations cited in the above paper are also inapplicable in "flatland," including the definitions of work, quantum units, and special relativity. I lack the expertise, time, or interest to follow this argument to any sort of conclusion, but would be fascinated to read if someone else had. A further brief googling, sadly, did not produce anything of interest.

@vasturiano
Copy link
Contributor Author

vasturiano commented Jul 7, 2020

@Fil I think you're right that the inverse-square relationship is because of the propagation in three dimensions. It makes sense.

So this question is really only relevant when using the force simulation to replicate behaviors of the physical 3-dimensional world, even if the representation itself is on a 2d plane. Like for instance simulating orbital patterns: https://bl.ocks.org/vasturiano/773c84f393afc98de3e99d551566481d

When the intent is strictly 2d graph drawing, the fidelity to natural real-world behavior is less of a concern. The emphasis is on efficient space utilization and, since computer screens are indeed a flatland artifact, probably linear relationships are more appropriate for that.

On d3-force-magnetic I actually added a distance relationship parameter that lets the consumer specify whatever math is desired. You can even switch from a gravity mode to a spring-like mode in which the strength increases with the distance instead of decaying.

@Fil
Copy link
Member

Fil commented Jul 8, 2020

Another physics metaphor is given in #139

@Fil Fil closed this as completed Sep 1, 2020
@Fil Fil added the idea label Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

5 participants
@Fil @mbostock @vasturiano @ddurschlag and others