Search code examples
pythonmathpygamecoordinatespow

How to offset the error in calculating cartesian coordinates from polar coordinates


I'm currently trying to develop a to-scale model of the universe using pygame. At the moment, when I'm calculating the x, y positions of the planets w.r.t. the sun, the planets are slowly falling towards the sun, despite only using equations for position based on the distance and angle of the planet (no force).

Here is the code snippet for calculating distance from a given star currently:

def d_obj(self, reference):

    x_diff_sq = pow(self.x - reference.pos[0], 2)
    y_diff_sq = pow(self.y - reference.pos[1], 2)
    return pow(x_diff_sq + y_diff_sq, 0.5)

And then I pass what this function returns into the next function for calculating the position

def move(self, d):
    self.theta += self.d_theta
    self.x = int(d * math.cos(self.theta)) + total_d/2
    self.y = int(d * math.sin(self.theta)) + total_d/2

total_d/2 is a co-ordinate offset and self.d_theta is the rotational period for the given planet.

Each planet has its initial position hard coded and I'm using this to calculate the difference between initial distance and current distance for all of the planets, every tick it is apparent that the planet moves about 1km towards the sun. Is there any way I can attempt to offset this?

I understand that in the scale of things where I'm drawing things in terms of millions of km, I'm just curious what part of these equations is causing the error. I've tried using the '**' operator over pow and after some research online found that pow is better used for powers involving floats.

Should also mention that all calculations are in kilometers, then before drawing, the planets radius and x, y are mapped to the screen from a set distance that is currently around 4 AU.


Solution

  • You're trying to move your planets in circles, right?

    In your code, you

    1. Use x and y to calculate distance,
    2. Use delta_theta to calculate new theta,
    3. Use new theta and distance to calculate new x and y.

    You don't have to do all that. Instead, you can keep a hardcoded distance and just

    1. Use delta_theta to calculate new theta,
    2. Use new theta and (known) distance to calculate x and y for drawing.

    Then your distance will not drift at all.


    Side note: If you're planning to keep the planets moving for long times, make sure you keep your theta between 0 and 2*pi, or rounding errors will start kicking in and your theta accuracy will deteriorate.


    You're thinking this will make adding moons and asteroids difficult.

    Not really!

    You can do the same for moons, by noting which planet they belong to, the distance to that planet, delta_theta and initial theta (based on their parent planet).

    If you want to start doing ellipses instead of circles, you can change your calculations (use convenient constant orbital elements instead of distance and delta_theta, which will not be constant anymore) to apply Kepler's laws.

    You can also add asteroids later. You can keep the Cartesian positions and velocities of the asteroids, and calculate their motion separately, after calculating the motion of all the "trivially" moving objects.