2

I'm dealing with a question for class that is asking me to mimic the movements of planets/moons/asteroids within a solar system in a 3D space. We started early the semester with vectors, masses, and forces, so I'm still trying to grasp it.

*My issues are detailed below on step 4 and 5. Let me know if I got anything wrong along the way. Any input and guidance would be greatly appreciated.

  • Info Given

Each object in space has the following:

  • mass
  • position vector <x, y, z>
  • velocity vector <x, y, z>

I have to use Newton's Law of Universal Gravitation:

F = G * mass1 * mass2 / distance^2
  • Question

Given time t update the position and velocity of each object in space. So if t is 10 seconds, where would those objects be in space at that given time?

I'm told to treat acceleration as constant throughout t. And not to worry about object collisions and that the objects may be extremely small, for simplicity's sake. Given objects in space may be from 1 to 100.

  • My Progress So Far

I'm not sure if I'm doing it right so far but here's the steps I'm taking so far:

Step 1: If it was 2 objects then I'd use the force formula as it as. But since it's X amount of objects I'm going through each object and I'm calculating the Force between itself and every other object. I'm adding those up to a Net Force.

Step 2: I'm calculating my Acceleration:

a = Net Force / Mass

Step 3: Next I calculate the final velocity:

V = u + a*t u = initial velocity

Step 4: Calculate the final position of the object:

s = s0 + u*t + 1/2*a*t^2 

s0 = initial position, u = initial velocity

Step 5: repeat the process on the rest of the objects

My problem is on step 4 and 5. My positions and velocities are vectors. but the acceleration is a scalar, so I know I just can't add that up to the vectors. So what do I do here? Do I do the calculation on each vector component then put all the components back into the new final velocity and final position vectors? I'd really appreciate the help and any input.

Spektre
  • 49,595
  • 11
  • 110
  • 380
NULL
  • 43
  • 1
  • 3
  • Note that [acceleration is a vector](https://en.wikipedia.org/wiki/Acceleration), and the force acting between any two bodies is a vector as well. – lr1985 Sep 19 '21 at 10:49
  • But my Net Force is a scalar value since all the variables like G, mass, and distance are scalar as well. Unless I messed up in my calculations, is distance supposed to be scalar or vector? As of right now I'm using distance as a scalar but maybe I should've used it as a vector (ObjectA.position - ObjectB.position)? – NULL Sep 19 '21 at 17:33
  • Distance is a vector. You are computing the *magnitude* of the force, but you need its vectorial form if you want to use it to integrate the equations of motion. You can find additional details [here](https://physics.info/gravitation/summary.shtml) – lr1985 Sep 19 '21 at 17:44
  • Ooooooh!!! I didn't know there was a vector form/notation for that formula. I thought I'd just have to use a vector distance instead of the magnitud, but I have to multiply the negative of that result with the unit distance vector. I get it now! – NULL Sep 19 '21 at 17:54

2 Answers2

0

First see this QA:

Your steps are completely wrong for dynamic n-body orbital mechanics !!!

Because your bodies are moving along curves You need to iterate the integral using Newton D'ALembert integration instead of computing the whole thing at once as the directions and forces are changing along the way or else your orbits would be distorted or even rotating or deviating toward sun or even escape in time. There are also integration methods preserving energy for this...

Also You have to compute all the forces from all bodies before any computation changes the positions of your bodies otherwise you will implement wrong directions as some bodies already computed are in new positions and others are not yet. This usually cause problems for close proximity bodies like moons and or fly by ...

I use this logic instead:

  1. for each body you need to have these:

    struct _body
     {
     double mass;
     dvec3 pos; // position
     dvec3 vel; // velocity
     dvec3 acc; // acceleration
     } body[n];
    

    also use at least 64bit double floating point for this. If you have more its even better as even 64bit float is at its limits for computations like this.

  2. for each body compute acceleration

    so simply sum up all the accelerations for each body

    for (i=0;i<n;i++) body[i].acc = dvec3(0,0,0);
    for (i=0;i<n;i++)
     for (j=i+1;j<n;j++) 
      {
      dvec3 d = body[i].pos - body[j].pos;
      dvec3 F = G * body[i].mass * body[j].mass * d / pow(length(d),3);
      body[i].acc -= F/body[i].mass; // the same force is aplied to both bodies
      body[j].acc += F/body[j].mass; // just in reverse direction
      }
    

    the d / pow(length(d),3); will give you vector in direction of d and size of 1/d^2. where length(d)=sqrt(d.x*d.x + d.y*d.y + d.z*d.z) This term converts your scalar equation into vector one ...

    You might also add some sanity check for the d size so you avoid the division by too small or zero value once your bodies crash into each other ...

  3. now you apply the changes for each body

    for (i=0;i<n;i++)
      {
      // Newton D'ALembert integration
      body[i].vel += body[i].acc*dt; // this is instead of V = u + a*t
      body[i].pos += body[i].vel*dt; // this is instead of s = s0 + u*t + 1/2*a*t^2
      }
    

    where dt is your iteration time step for example 0.1 sec (or timer interval or elapsed or simulated time step) iteration time step greatly impacts precision So if you need more precision I recommend to use the precision enhancing trick from the linked answer above it hugely improves things without significantly lowering dt.

    Also note is crucial that steps #2 and #3 are in separate loops do not merge them together!!!

  4. go to #2

    so you repeat steps #2,#3 during your simulation using timer, or thread with some sleep(dt) or whatever mechanism your simulation engine uses for timing.

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • The professor told us to treat acceleration as constant throughout the time steps and to completely ignore collision. He also pointed out that since double is not exactly accurate/precise and we're simulating this is discrete time steps, that there will be inaccurate final results and that it was totally fine, to not worry about that. Oh, and to use the vector form of Newton's Law of Universal Gravitation. So with that in mind: 1) constant acceleration 2) discrete time steps 3) No collision 4) Expected inaccurate results. - is my approach still incorrect? – NULL Sep 20 '21 at 17:26
  • 1
    @NULL only if `u,s0` are values from previous iteration and the `t` is the the time step/increment and not the simulation time itself. However the `Newton D'ALembert integration` is better (if you integrate it back to static time form it will expand to more or less the same as your equation for `s`) ... however Your description has merged the computation of force/acceleration and updating speed and position into single loop which will lead to much more inaccuracy. My answer satisfy all your conditions too btw. – Spektre Sep 20 '21 at 18:06
  • That's correct, the time 't' given is more like a snapshot of what the positions and velocities will look like in that given 't' as well as 'u,s0' being from previous iterations. So we're basically moving to that time in an instant. I don't doubt you in Newton D'ALembert integration being a better option, but because of the instructions, I'm required to use the vector form of Newton's Law of Universal Gravitation. – NULL Sep 20 '21 at 18:37
  • 1
    @NULL `vector form of Newton's Law of Universal` refer to this: `F = G * body[i].mass * body[j].mass * d / pow(length(d),3); acc = F/mass; vel = integral(acc); pos=integral(vel);` using rectangular rule integration leads to `vel += acc*dt; pos += vel*dt` ... the equations of yours for `s` is just using finite integral on interval `<0,dt>` instead but the result is the same the difference is rounding errors due to more complicated operations used. – Spektre Sep 20 '21 at 20:26
0

If professor told you to treat acceleration as constant throughout the time steps then do so and also take it as vector which doesn't change with respect to time.

your Acceleration can be

vec3 acc = vec3( accVal, accVal, accVal );

this will give you a acceleration that is constant on all three Axis.