#include #include #include #define PI 3.141592653589793 #define SOLAR_MASS (4 * PI * PI) #define DAYS_PER_YEAR 365.24 #define NP 5 #define ADVANCE 0.01 struct Body { double x, y, z, vx, vy, vz, mass; }; inline double energy(const Body bodies[5]) { double e = 0.0; for (int i = 0; i < NP; ++i) { const Body& i_planet = bodies[i]; const double i_planet_mass = i_planet.mass; for (int j = i + 1; j < NP; ++j) { const Body& j_planet = bodies[j]; const double dx = i_planet.x - j_planet.x; const double dy = i_planet.y - j_planet.y; const double dz = i_planet.z - j_planet.z; e -= (i_planet_mass * j_planet.mass) / sqrt( (dx * dx) + (dy * dy) + (dz * dz)); } const double i_planet_vx = i_planet.vx; const double i_planet_vy = i_planet.vy; const double i_planet_vz = i_planet.vz; e += 0.5 * i_planet_mass * ((i_planet_vx * i_planet_vx) + (i_planet_vy * i_planet_vy) + (i_planet_vz * i_planet_vz)); } return e; } int main(int argc, const char* argv[]) { Body bodies[NP] = { { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS }, { 4.84143144246472090e+00, -1.16032004402742839e+00, -1.03622044471123109e-01, 1.66007664274403694e-03 * DAYS_PER_YEAR, 7.69901118419740425e-03 * DAYS_PER_YEAR, -6.90460016972063023e-05 * DAYS_PER_YEAR, 9.54791938424326609e-04 * SOLAR_MASS }, { 8.34336671824457987e+00, 4.12479856412430479e+00, -4.03523417114321381e-01, -2.76742510726862411e-03 * DAYS_PER_YEAR, 4.99852801234917238e-03 * DAYS_PER_YEAR, 2.30417297573763929e-05 * DAYS_PER_YEAR, 2.85885980666130812e-04 * SOLAR_MASS }, { 1.28943695621391310e+01, -1.51111514016986312e+01, -2.23307578892655734e-01, 2.96460137564761618e-03 * DAYS_PER_YEAR, 2.37847173959480950e-03 * DAYS_PER_YEAR, -2.96589568540237556e-05 * DAYS_PER_YEAR, 4.36624404335156298e-05 * SOLAR_MASS }, { 1.53796971148509165e+01, -2.59193146099879641e+01, 1.79258772950371181e-01, 2.68067772490389322e-03 * DAYS_PER_YEAR, 1.62824170038242295e-03 * DAYS_PER_YEAR, -9.51592254519715870e-05 * DAYS_PER_YEAR, 5.15138902046611451e-05 * SOLAR_MASS } }; { double px = 0.0; double py = 0.0; double pz = 0.0; for (int i = 1; i < NP; ++i) { const Body& planet = bodies[i]; const double planet_mass = planet.mass; px += planet.vx * planet_mass; py += planet.vy * planet_mass; pz += planet.vz * planet_mass; } Body& sun = bodies[0]; sun.vx = -px / SOLAR_MASS; sun.vy = -py / SOLAR_MASS; sun.vz = -pz / SOLAR_MASS; } printf("%.9f\n", energy(bodies)); for (int x = 0, n = atoi(argv[1]); x < n; ++x) { for (int i = 0; i < NP; ++i) { Body& i_body = bodies[i]; const double i_body_x = i_body.x; const double i_body_y = i_body.y; const double i_body_z = i_body.z; const double i_body_mass = i_body.mass; for (int j = i + 1; j < NP; ++j) { Body& j_body = bodies[j]; const double dx = i_body_x - j_body.x; const double dy = i_body_y - j_body.y; const double dz = i_body_z - j_body.z; const double d_squared = (dx * dx) + (dy * dy) + (dz * dz); const double mag = ADVANCE / (d_squared * sqrt(d_squared)); const double j_mag = j_body.mass * mag; const double i_mag = i_body_mass * mag; i_body.vx -= dx * j_mag; i_body.vy -= dy * j_mag; i_body.vz -= dz * j_mag; j_body.vx += dx * i_mag; j_body.vy += dy * i_mag; j_body.vz += dz * i_mag; } } for (int i = 0; i < NP; ++i) { Body& body = bodies[i]; body.x += ADVANCE * body.vx; body.y += ADVANCE * body.vy; body.z += ADVANCE * body.vz; } } printf("%.9f\n", energy(bodies)); return 0; }