float T = 30.f; // Period (s) float GM = 4.f*PI*PI/T/T; // Gravitational constant float[] x = {1.f, 0.f, 0.f, -2.f*PI/T}; // Initial state for circular orbit // Compute x_dot = f(x). void dynamics(float x[], float xd[]) { float g = -GM/pow(sqrt(x[0]*x[0] + x[1]*x[1]), 3); xd[0] = x[2]; // p_dot = v xd[1] = x[3]; xd[2] = g * x[0]; // v_dot = a xd[3] = g * x[1]; } // Update with RK4. void rk4(float x[], float dt) { float[] k1 = {0.f, 0.f, 0.f, 0.f}; float[] k2 = {0.f, 0.f, 0.f, 0.f}; float[] k3 = {0.f, 0.f, 0.f, 0.f}; float[] k4 = {0.f, 0.f, 0.f, 0.f}; float[] xf = {0.f, 0.f, 0.f, 0.f}; dynamics(x, k1); for (int i = 0; i < 4; ++i) { xf[i] = x[i] + 0.5 * dt * k1[i]; }; dynamics(xf, k2); for (int i = 0; i < 4; ++i) { xf[i] = x[i] + 0.5 * dt * k2[i]; }; dynamics(xf, k3); for (int i = 0; i < 4; ++i) { xf[i] = x[i] + dt * k3[i]; }; dynamics(xf, k4); for (int i = 0; i < 4; ++i) { x[i] += dt/6. * (k1[i] + 2.*k2[i] + 2.*k3[i] + k4[i]); } } // Reset on click. //void mousePressed() { // x[0] = 1.f; x[1] = 0.f; x[2] = 0.f; x[3] = -2.f*PI/T; //} // Set up the scene. void setup() { size(400, 300, P3D); background(0); } // Clear, propagate planets from last step to now, draw. int t = 0; void draw() { // Figure out how much time has passed. int t_now = millis(); float dt = min(((float)(millis() - t)) / 1000.f, 1.f); if (dt < 0.05 || t_now < 2000) { return; } // Don't work excessively hard. t = t_now; rk4(x, dt); // Update with RK4. // Draw. background(0); // Black background pushMatrix(); translate(width/2, height/2, 0); // Center things. float sun = t_now/1000.f * TWO_PI/(12.f*T); // Move the sun, just for kicks. pointLight(255, 255, 255, -1000 * sin(sun), -1000 * cos(sun), 0); translate(0, 0, -150); // Push the planets deeper into the view. noStroke(); // Draw planet with no stroke fill(64, 196, 64); // with this color sphere(50); // as a sphere with radius 50. pushMatrix(); translate(200.f * x[0], 200.f * x[1], 0.f); // Move to moon's position. fill(0, 128, 196); // Set moon's color. sphere(20); // Draw moon sphere. popMatrix(); popMatrix(); }