1
votes

I've created a simple planetary simulation where a planet orbits a star. The code for the orbit is this:

    a = a + vel * delta;
    planetX = Math.cos(a) * orbitRadius + parentStar.getX();
    planetY = Math.sin(a) * orbitRadius + parentStar.getY();

Now that works just fine, but my problem is that the orbit is not from the center of the planet around the center of the star. This is what happens

As you can see, the first red dot on the small circle is the Position of the planet wich orbits around the second small red dot, this is because the circle is drawn from (0,0), so both the planets (0,0) circles around the (0,0) of the star.

I need the the center of the planet to circle the stars center, not their origin point.

Is there a good fix for this?

2
can I assume parentStar is rectangle? why dont you give us the full code; the static picture doesnt explain anythinggpasch
@gpasch Because all other code is just creating the image and drawing it, and yes, they are circles in a rectangular image.GigaNova

2 Answers

3
votes

Your calculation of the orbit is fine. The only problem seems to be that you treat "position" differently when calculating orbits and when drawing the planets: When you draw them, you treat x and y as one of the corner points, but when you calculate the oribit, you treat them as the centre of the body. The simplest way would be to change the visualisation, not the calculation.

Since you did not post the code you use to draw the shapes, I can only guess, but I assume it looks somewhat like this (obviously Pseudocode):

for (Planet p : starsAndPlanets) {
    drawCircle(p.x, p.y, p.radius * 2, p.radius * 2);
}

Change this to something like this:

for (Planet p : starsAndPlanets) {
    drawCircle(p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2);
}

This way, x and y are the position of the centre of the planet, and with p.x - p.radius and p.y - p.radius you get the corner point. Of course, you could in a similar way change all your orbital mechanic formulas to calculate the centre from the corner point, but IMHO it is much simpler and more natural to treat x and y as the centre.

0
votes

For now the most suitable way I can think of is getting the star's world coordnates and passing them every frame to the child's coordinates. As you do so, the child would have the same coordinates everyframe.

The next part is translating it and rotating it around the Star - the way you can achieve that is by setting the planet's position to be transposed by the Star's position with a sin(x)*cos(x).

Let me show you an example:

planet[0] = star[0] + sin(angle)*scale

planet[1] = star[1] + cos(angle)*scale

Where the angle would change incrementally and the scale will just shift the child object further from its parent, keeping it a constant (or modifying it if you wish) thus increasing the radius from its 'new' center.

I know some people may mention matrices or other types of transformations, but for this situation I think the above solution would be most relevant and cleanest in my opinionp

The way it works is you take the parent's 'WORLD coordinates' and set them to be the child's. By modifying the Scale value you increase the distance of the object from the center (so they won't overlap) and you multiply this with the sin and cos of the angle you specified to make it rotate.

P.S. Keep in mind that if you're dealing an FPS-dependant engine to render, the more FPS the faster the simulation will be, and vice-versa, because if you render at 1000 fps, this means you execute your code 1000 times, compared to 100 for example. Therefore, you will increment the angle 1000 times or 100 respectively. If you have this issue, try setting a constant framerate if you can - it's the simplest workaround for lightweight simulations.

Edit: I forgot to mention that the concept works for all objects in your case. You just have to work our the relationships and use the function for eqch object seperately where each object has a position and angle of orbit (if it orbits around a different object).