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

Numerical integration seems odd #17

Open
won3d opened this issue Jan 12, 2021 · 6 comments
Open

Numerical integration seems odd #17

won3d opened this issue Jan 12, 2021 · 6 comments

Comments

@won3d
Copy link

won3d commented Jan 12, 2021

https://github.com/pablo-mayrgundter/celestiary/blob/5c8e5f2b32272cf07a95f450987bb16596acbba8/js/Galaxy.js#L116-L124

What are lines 118 and 119 for?

On the plus side, lines 120-122 seem to be doing semi-implicit Euler integration, which is a reasonable choice. Basically, the order you accumulate velocity and position matters. Doing:

position += velocity
velocity += acceleration

Isn't as stable as vanilla Euler:

velocity += acceleration
position += velocity

To be clear, that seems to be what you are already doing, but you should note that the order of accumulation matters.

A bonus thought:

A lot of physical simulations will do something slightly different called Verlet integration. I think it has some nicer properties than the Euler variants without being too much more complicated. You could even argue that it is conceptually simpler because it doesn't explicitly even use velocity. This is nice because a lot of more simulations will have constraints on positions, and when you go to enforce them you have to make sure your velocities are also corrected. Not having explicit velocities avoids that .Or maybe you want to draw streaks behind the particles, where you'll need the old positions. But most importantly, Verlet is just a more accurate numerical integrator.

Verlet works by reconstructing velocity from positions. You want to do something like:

pos_after = pos_now + vel + accel

You can recover vel with finite differences:

vel == pos_now - pos_before

When you substitute you get:

pos_after = 2*pos_now - pos_before + accel

In practice, pos_old and pos_next can be the same storage -- you're effectively double-buffering. In the context of ThreeJS, I don't know if that's a good thing or a bad thing. It is possible that ThreeJS tightly couples GPU and CPU vertex buffer storage layouts, which makes updating a buffer not as simple as just setting a flag. There are lots of ways around it but I'd have to know how ThreeJS worked better, and what you would want to accomplish.

@pablo-mayrgundter
Copy link
Collaborator

pablo-mayrgundter commented Jan 12, 2021 via email

@won3d
Copy link
Author

won3d commented Jan 14, 2021

Instead of if (this.first) {} can't you set it up when the positions get initialized?

I'd save the Verlet stuff for later if it gives you any trouble. Semi-implicit Euler isn't too bad and you'll want to get things working before you start making structural changes, however minor.

@pablo-mayrgundter
Copy link
Collaborator

pablo-mayrgundter commented Jan 14, 2021 via email

@won3d
Copy link
Author

won3d commented Jan 15, 2021

It looks like the "a" in that equation isn't acceleration but axis-length (aka radius)?

@pablo-mayrgundter
Copy link
Collaborator

pablo-mayrgundter commented Jan 15, 2021 via email

@won3d
Copy link
Author

won3d commented Jan 15, 2021

Oh I see, yeah that makes sense! I don't think I ever thought to do it this way, even though in retrospect this is clearly the right way to do it. I always just set velocity as a function of radius, and kind of just approximated what the expected inward acceleration ought to be. You already have a full simulation function, no need to try to do anything analytically, I'd say.

As a tangent, there's something that almost applies: Gauss's Shell Theorem: https://en.wikipedia.org/wiki/Shell_theorem

If you have some force that is inverse-square, like gravity or charge, then spherically symmetric distributions have a nice simplification: a particle can ignore all of the mass that is further than the center of mass than itself. Unfortunately, I don't think this applies to mass distributions around a disk. So some analog exists, but I don't think it would be as nice. But I could be wrong! It would be interesting to plot the results of the force magnitude vs. radius.

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

No branches or pull requests

2 participants