// gcc c.c -Wall -std=c99 -lm #include #include #include #include #define C const typedef long double R; static R pi = 3.14159265358979323846L; typedef struct{R x, y, t;} sl; typedef struct{R x[3], xd[3];} co; static R fm(R a, R m){return a - m*floorl(a/m);} static co Kepler(R e, R L){sl w = {1, 0, 0}; static R Cos[64], Sin[64]; {static char first = 1; if(first){R b = 4; first = 0; for(int j=0; j<64; ++j) {Cos[j] = cosl(b); Sin[j] = sinl(b); b /=2;}}} R a = 1/(1 - e*e), ys = sqrtl(a), ts = 1/(a*ys); R M = fm(L, 2*pi); {R dt = 4; for(int j=0; j<64; ++j){sl q = {w.x*Cos[j] - w.y*Sin[j], w.x*Sin[j] + w.y*Cos[j], w.t + dt}; dt *= .5; if(q.t - e*q.y < M) w = q;}} assert(fabsl((w.t - e*sinl(w.t)) - M) < 1.e-18); {R sp = ts/(1 - e*w.x); return (co){{(w.x - e)*a, w.y*ys, 0}, {-w.y*a*sp, w.x*ys*sp, 0}};}} void pco(char * m, co x){printf("co %s:\n", m); for(int j=0; j<3; ++j) printf("%15.12Lf %15.12Lf\n", x.x[j], x.xd[j]);} //typedef struct{R a, e, i, Omega, omega, L;} elm; typedef R elm[6]; co trco(R m[3][3], co a){ typedef struct{R m[3];} zz; zz mm(R y[3]){zz z; for(int k=0; k<3; ++k){ R s=0; for(int j=0; j<3; ++j) s += y[j]*m[k][j]; z.m[k] = s;} return z;} {zz z = mm(a.x), zd = mm(a.xd); co c; for(int j=0; j<3; ++j) {c.x[j] = z.m[j]; c.xd[j] = zd.m[j];} return c;}} static co initp(elm p){ R cpi = pi/180; co n = Kepler(p[1], (p[5] - p[4])*cpi); R op = p[4]*cpi, Om = p[3]*cpi, in = p[2]*cpi, e = p[1], A = p[0]*(1-e*e); R uo[3][3] = {{cosl(op), -sinl(op), 0},{sinl(op), cosl(op), 0},{0,0,1}}; R ui[3][3] = {{cosl(in), 0, -sinl(in)}, {0,1,0}, {sinl(in), 0, cosl(in)}}; R uO[3][3] = {{cosl(Om), -sinl(Om), 0},{sinl(Om), cosl(Om), 0},{0,0,1}}; R ua[3][3] = {{A, 0, 0}, {0, A, 0}, {0, 0, A}}; R P = 1/sqrtl(p[0]*p[0]*p[0]); // 1/(period of orbit in years). for(int j=0; j<3; ++j) n.xd[j] *= P; return trco(ua, trco(uO, trco(ui, trco(uo, n))));} #define np 9 static elm planets[np] = { { 0.38709893, 0.20563069, 7.00487, 48.33167, 77.45645, 252.25084}, { 0.72333199, 0.00677323, 3.39471, 76.68069, 131.53298, 181.97973}, { 1.00000011, 0.01671022, 0.00005, -11.26064, 102.94719, 100.46435}, { 1.52366231, 0.09341233, 1.85061, 49.57854, 336.04084, 355.45332}, { 5.20336301, 0.04839266, 1.30530, 100.55615, 14.75385, 34.40438}, { 9.53707032, 0.05415060, 2.48446, 113.71504, 92.43194, 49.94432}, {19.19126393, 0.04716771, 0.76986, 74.22988, 170.96424, 313.23218}, {30.06896348, 0.00858587, 1.76917, 131.72169, 44.97135, 304.88003}, {39.48168677, 0.24880766, 17.14175, 110.30347, 224.06676, 238.92881}}; co state[np+1]; static elm planetsD[np] = { { 0.00000066, 0.00002527, -23.51, -446.30, 573.57, 538101628.29}, { 0.00000092, -0.00004938, -2.86, -996.89, -108.80, 210664136.06}, {-0.00000005, -0.00003804, -46.94, -18228.25, 1198.28, 129597740.63}, {-0.00007221, 0.00011902, -25.47, -1020.19, 1560.78, 68905103.78}, { 0.00060737, -0.00012880, -4.15, 1217.17, 839.93, 10925078.35}, {-0.00301530, -0.00036762, 6.11, -1591.05,-1948.89, 4401052.95}, { 0.00152025, -0.00019150, -2.09, -1681.40, 1312.56, 1542547.79}, {-0.00125196, 0.0000251, -3.64, -151.25, -844.43, 786449.21}, {-0.00076912, 0.00006465, 11.07, -37.33, -132.25, 522747.90}}; static void ex(char * s){exit(printf("dying: %s\n", s));} static void init(){if(sizeof(planets)/sizeof(elm) != np) ex("nxp"); for(int j = 0; j