🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Gravitational acceleration calculation

Started by
143 comments, last by taby 1 year, 10 months ago

@JoeJ . Ya, especially constraining the force values. It seems it's necessary due to the error that arises in the calculations.

None

Advertisement
for (let i = 0; i < stars.length; i++) {
    for (let j = 0; j < stars.length; j++) {
      // We don't want to calculate the same star against itself
      if (i === j) continue;

Notice this processes each pair twice: First i,j and later j,i again, doing the same calculations.

You can just write:

for (let i = 0; i < stars.length-1; i++) {
    for (let j = i+1; j < stars.length; j++) {

Does only half of the work, and no self-check needed.

But then you also need to change the Attract function so it adds the force to both bodies. Thus it should be no member function of the star class, as it affects a pair of stars.
In practice it should run twice as fast after the changes.

jonny-b said:
There is a black hole star that has more mass than the others combined and it doesn't interact in the way I thought.

It has just 10 times the mass, that's not much. I tried 1000 times. The whole universe started to wobble in a interesting way.
But the distance clamping will surely have an effect. I do not see a need to constrain max distance which causes only weak forces. You could just constrain the minimum distance to avoid div by 0.
Or add some constant (to prevent discontinuities from clamping), which i have tried:

// dsquared = constrain(dsquared, 100, 9999);
    dsquared += 100;

I also put the big star to the center, so i can more likely see what happens to that:

// Black hole
  stars.push(new Star(750/2, 750/2, 100000, 1));

But it flies out of the canvas, whil i would expect it sticks close to the center, attracting all other stars.

Maybe you did not respect star mass when integrating the force…

…yes:

update() {
    this.vel.add(this.acc); // it is force, not yet acceleration. To convert it to acceleration we need mass: acc = force / mass
    this.pos.add(this.vel);
    this.acc.mult(0);
  }

I fix this:

update() {
    this.vel.add(this.acc / this.mass);
    this.pos.add(this.vel);
    this.acc.mult(0);
  }

Now math may be right, but variable name is wrong. You need to change it to force, or do the division in the Attract function already, but that's n*n divisions vs. n divisions, so slower.

However, now stuff does not move at all, or very slowly.
Tried to increase masses but no luck. Another option would be to introduce a timestep larger than one. You can see this in my code example above.

@joej , I'm pretty sure we need to compare i→j and later j→i Both of them are exerting a force on the other and we need to capture that. By doing the -1 and +1 we are ensuring that (-1) we never calculate anything for the last star in the array and for (+1) we leave out a bunch of stars from the whole equation. However, i do see your point about missing mass in the F = M * A equation. Great Catch!!! I think what is happening is each star is adding its own mass to the star it is calculating against. This would explain why the black hole shoots around so fast but the other stars also seems to react to it like it is more massive.

None

jonny-b said:
Both of them are exerting a force on the other and we need to capture that.

Yes, but forceAtoB = -forceBtoA.

@JoeJ It's not zero sum though. Star a gets a pull towards star b. Then star b gets a tug towards star a. In your model I think one of those stars doesn't get tugged on. For instance, in reality if you had a really massive object they still wobble under the influence of a smaller one. Either way. I got it workeing pretty well by adding in your suggestion of dividing by mass!! Glad you caught that. https://codepen.io/jonny-b/pen/NWyaJNd?editors=1011

None

jonny-b said:
In your model I think one of those stars doesn't get tugged on.

Make a little script and print both i and j from the inner loop. You will see it covers all possible pairs, skips i==j, and does no pair twice. Do this to eliminate your doubt.

It's no optimization, just the least you should do for n-body problems. If you don't, the impression is you can not write performant code. /:O\

Otherwise the simulation looks nice now : )

@JoeJ Hmm, I did your solution with just a black hole and a single star and the black hole never moved at all. Then I tried all stars and I noticed that one star would never move. The simulation now appears to be working as expected. Either way I really appreciate your help!

None

jonny-b said:
Hmm, I did your solution with just a black hole and a single star and the black hole never moved at all. Then I tried all stars and I noticed that one star would never move.

Then you did something wrong. It's not ‘my’ method. Everybody uses this, there are just some variants of this same thing.

A matter of minutes to proof it, but do i need to register to fork your project, and be able to save my changes?

@JoeJ Sorry. not trying to be argumentative. I think you probably do.

None

No problem, but you must be stopped doing this ;D

Seems ok: https://codepen.io/joedoej/pen/xxYPjJZ?editors=0011

Now you can do twice the stars in the same time.

This topic is closed to new replies.

Advertisement