0

I have a function that moves a planet around a star. This function takes a parameter t, which is the time in milliseconds since the last update. In other movement functions I've written, I like to use time to dictate movement so the movement will always be the same on all computers and instances instead of based on processing power. However, all methods I have tried for including time in this physics equation have resulted in erratic results. Any ideas?

void Planet::update(int t){
  double grav_const = 6.6742e-11;
  double earth_mass = 5.975e24;
  double starX = 1920/2 * 10000;
  double starY = 1080/2 * 10000;
  double diffX = xPos - starX;
  double diffY = yPos - starY;

  double radius = sqrt(pow(diffX,2) + pow(diffY,2));

  double grav_accel = (grav_const * (earth_mass / pow(radius,2)));
  double angle = atan2(diffX, diffY);
  xVel += (sin(angle) * grav_accel);
  yVel += (cos(angle) * grav_accel);
  xPos -= xVel;
  yPos -= yVel;
}
JakeP
  • 327
  • 3
  • 14
  • 1
    Where did you use the parameter t? – 2785528 Jul 07 '15 at 03:17
  • You're asking for position as a function of time in a general orbit, which is a somewhat messy calculation. I urge you to try something simpler first, like a solution for circular orbits. – Beta Jul 07 '15 at 21:54

2 Answers2

0

When you describes the results as "erratic" exactly what do you mean?

If you mean:

A. "t changes by a varying amount between each call". Then you need to look at the architecture of the calling application since that will vary with processing power and other work going on in the system (assuming a preemptive multitasking OS).

B. "the floating point values have strange rounding characteristics". Then welcome to using floating point numbers. The representations of double, float and the like are simply imperfect and exhibit rounding areas in certain circumstances and you may have problems if you are taking deltas that are too small relative to the size of the other values you are combining.

C. "t has no effect on my results". I don't see any references to the input parameter in your example.

You should post the entire Planet class, or at least more of it.

EDIT: The best way to calculate position based on times like this is to come up with an absolute function that returns position based on time and NOT accumulate position, but only accumulate time. For example:

timeAbsolute += tDelta;
xPos = fxPos(timeAbsolute);
yPos = fyPos(timeAbsolute);
xVel = fxVel(timeAbsolute);
yVel = fyVel(timeAbsolute);

My orbital mechanics fu is not strong enough to give you those functions in general, but in your case (where you seem to be assuming a circular orbit), you can simply take the arc angle instead. So, assuming 1 orbit every 360 seconds (and using degrees), you would get

angle = (timeAbsolute % 360);

then calc velocity and position from angle.

P.S. Be careful with fmod ... How to use fmod and avoid precision issues

Community
  • 1
  • 1
Brad
  • 3,190
  • 1
  • 22
  • 36
  • The results are erratic in that the orbit is changing instead of remaining the same. If t is very large, I want the planet to move less that tick because less time has gone by. If t is small, the planet should move more to compensate. (It would look laggy I suppose but it would be accurate.) The orbit should not change at all. And neither should the time it takes to make an orbit. However using t in my equation makes both of those things happen. – JakeP Jul 07 '15 at 02:15
  • You are still being very vague - Your sample code doesn't reference t so we can't really advise you... – Brad Jul 07 '15 at 02:28
  • This is literally all the code that has to do with xPos and yPos. t is the amount of milliseconds that have gone by since the last tick. On my computer, it averages out to about 16. EDIT: The problem does not lie with my calculation of t. That has been tested and confirmed. My problem is how to incorporate t into my xPos and yPos calculation. – JakeP Jul 07 '15 at 02:30
  • Where is 't' used in the function? EDIT: Where were you putting 't' when it didn't work right? – Brad Jul 07 '15 at 02:32
  • Well since I figured it was inversely proportional, I tried dividing by t in my xPos and yPos calculation. So `xPos -= xVel * t; yPos -= yVel * t;` – JakeP Jul 07 '15 at 02:38
  • I suspect your problem is accumulating errors in xVel & yVel over the varying amount of 't'. To get the real change in velocity you would need to account for the fact that velocity is the result of a differential equation with time (non-circular orbits). Therefore, if the values of 't' change much you're likely to get rounding differences that will eventually accumulate an error in the velocities which will then translate to errors in position. The best way to calc based on time like this is to come up with an absolute function that returns position based on time and NOT accumulate. – Brad Jul 07 '15 at 02:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/82549/discussion-between-brad-and-jakep). – Brad Jul 07 '15 at 02:57
0

It's been a while since I dealt with physics at this level, but I think you can go back to fundamental reasoning about the units involved.

Acceleration is distance over time squared (m/s^2 or whatever your units are). So to get velocity (distance over time) then you need to multiply by time.

m/s = (m/s^2) * s

And then after that you want to turn your velocity into a specific change in distance. So multiply it by the time again and there you go.

m = (m/s) * s

If things still don't seem right afterwards, then you may need to check over the rest of your equations and constants. Make sure the units match up (seconds vs minutes, metere vs kilometers, etc). Make sure you aren't suffering rounding in places you didn't intend. And so on.

In the worst case, work the math yourself for a few iterations (perhaps with larger time values) and maybe even plot the results on a piece of paper to make sure it looks sensible.

TheUndeadFish
  • 8,058
  • 1
  • 23
  • 17