I think it makes sense to use a 3D renderer, regardless if you want more of a 2D rendering style.
Here's a simple simulated example (without any physics).
Code:
Planet p1, p2, p3, p4, p5;
void setup(){
size(400, 400, P3D);
p1 = new Planet(0, 2, #DD33CC);
p2 = new Planet(45, 3, #EE9922);
p3 = new Planet(135, 5, #3399FF);
p4 = new Planet(225, 6, #55EE33);
p5 = new Planet(300, 2, #99FFEE);
}
void draw(){
background(0);
translate(width/2, height/2);
rotateX(radians(55));
p1.orbit(50, 55, 2.4, true);
p2.orbit(120, 132, 1.2, true);
p3.orbit(60, 66, 1.7, true);
p4.orbit(150, 165, 2.75, true);
p5.orbit(20, 22, 1.75, true);
}
class Planet{
float planetOffset;
float planetRadius;
color surface;
float angle;
boolean isPathVisible;
Planet(float planetOffset, float planetRadius, color surface){
angle = planetOffset;
this.planetRadius = planetRadius;
this.surface = surface;
}
void orbit(float ellipticalRadiusX, float ellipticalRadiusY,
float orbitSpeed, boolean isPathVisible){
// draw ellipse first, so it's under the planet
if (isPathVisible){
drawOrbit(ellipticalRadiusX, ellipticalRadiusY);
}
float px = cos(radians(angle))*ellipticalRadiusX;
float py = sin(radians(angle))*ellipticalRadiusY;
fill(surface);
noStroke();
ellipse(px, py, planetRadius*2, planetRadius*2);
angle+=orbitSpeed;
}
void drawOrbit(float ellipticalRadiusX, float ellipticalRadiusY){
stroke(255, 50);
float angle=0;
for (int i=0; i<360; i++){
point(cos(radians(angle))*ellipticalRadiusX,
sin(radians(angle++))*ellipticalRadiusY);
}
}
}
-ira