Reputation: 23
I'm trying to make a tiny solar system in java with simple orbits (no gravity or anything fancy).
I want: A moon orbiting around a planet, orbiting around a sun.
My issue: The "moon" has an eliptical orbit instead of an circular one.
The code i use:
void movePlanet(){
// set referencePoint as origin
double x1 = this.x - referencePoint.getX();
double y1 = this.y - referencePoint.getY();
// apply the rotation matrix (i think, i don't really understand this part)
double x2 = x1 * Math.cos(rotationAngle) - y1 * Math.sin(rotationAngle);
double y2 = x1 * Math.sin(rotationAngle) + y1 * Math.cos(rotationAngle);
// move everything back into position
this.x = x2 + referencePoint.getX();
this.y = y2 + referencePoint.getY();
So, the sun is static. The planet use this function, and it work fine. The referencePoint is the sun, and "this" is the planet. The moon use this function too, the referencePoint is the planet, and "this" is the moon.
I think i'm stuck on this because i don't understand how the rotation matrix work.
Edit1:
More context:
planete[] planetes = new planete[8];
// arguments: ReferencePoint, orbitRadius, rotationTime, size, sprite
// planet/moon cordinates are:
// x:referencePoint + orbitRadius
// y:referencePoint
planetes[0] = new planete(Sun, 100, 10, 32, "earth.gif"); // Planet
planetes[1] = new planete(planetes[0], 50, -5, 32, "earth.gif"); // moon
while (horloge.giveDayCountSinceStarting() < timeLimit) { // drawing loop
StdDraw.clear(Color.BLACK); // On efface le "tableau"
Sun.showAstre(); // display the sun
for (planete planete : planetes) {
if (planete != null) {
planete.drawOrbit(); //display planet orbit
planete.showAstre(); //display planet
planete.movePlanet(); // move planet
}
}
StdDraw.show();
StdDraw.pause(1000 / refreshRate);
}
EDIT 2: Explanation of the answer, thanks to Dawood ibn Kareem:
My error was in the operations order:
Move planet to origin - Apply rotation on planet - Move planet back
Move moon to origin - Apply rotation on moon - Move moon back
But when the moon starts its rotation, the planet has already finished its own. So the moon turns "twice as much". That's why at the maximum of the gap, it's 2 times its supposed orbit.
The solution was to save the position of the planet BEFORE its rotation. When the moon will make its rotation, it will take the position of the planet before its rotation, and not after, not to cumulate the rotations.
Upvotes: 1
Views: 287
Reputation: 79808
Your logic should be something like this. This applies one rotation angle to the distance between the moon and the planet, and another rotation angle to the distance between the planet and the sun.
double moonDisplacementX = moon.getX() - planet.getX();
double moonDisplacementY = moon.getY() - planet.getY();
double planetDisplacementX = planet.getX() - sun.getX();
double planetDisplacementY = planet.getY() - sun.getY();
double planetNewDisplacementX
= planetDisplacementX * Math.cos(planetRotation) - planetDisplacementY * Math.sin(planetRotation);
double planetNewDisplacementY
= planetDisplacementX * Math.sin(planetRotation) + planetDisplacementY * Math.cos(planetRotation);
planet.setX(sun.getX() + planetNewDisplacementX);
planet.setY(sun.getY() + planetNewDisplacementY);
double moonNewDisplacementX
= moonDisplacementX * Math.cos(moonRotation) - moonDisplacementY * Math.sin(moonRotation);
double moonNewDisplacementY
= moonDisplacementX * Math.sin(moonRotation) + moonDisplacementY * Math.cos(moonRotation);
moon.setX(planet.getX() + moonNewDisplacementX);
moon.setY(planet.getY() + moonNewDisplacementY);
Notice how the moon's new displacement vector is added to the planet's new position, not its original position. This is what keeps the moon tied to the planet.
Upvotes: 1