#include #include #define pi 3.14159265358979323 #define dtor (pi/180.0) struct orbel { double O; double i; double w; double a; double e; double M; double Odot; //time unit = 1 day double idot; double wdot; double adot; double edot; double Mdot; }; double getd(int y, int m, int d, int h) { return (long)367 * y - 7 * (y + (m + 9) / 12) / 4 + 275 * m / 9 + d - 730531.5 + h / 24.0; } void getplanetels(struct orbel *p); void getplanetphases(double *x, double *y, double *z, double *vx, double *vy, double *vz, double d, double dt); void calcpos(double *x, double *y, double *z, double O, double i, double w, double a, double e, double M); void calcposel(double *x, double *y, double *z, struct orbel *elements, double d); void calcphaseel(double *x, double *y, double *z, double *vx, double *vy, double *vz, struct orbel *elements, double d, double dt); void getplanetels(struct orbel *p) { p[1].O = 48.3313; p[1].Odot = 3.24587E-5; p[1].i = 7.0047; p[1].idot = 5.00E-8; p[1].w = 29.1241; p[1].wdot = 1.01444E-5; p[1].a = 0.387098; p[1].adot = 0; p[1].e = 0.205635; p[1].edot = 5.59E-10; p[1].M = 168.6562; p[1].Mdot = 4.0923344368; p[2].O = 76.6799; p[2].Odot = 2.46590E-5; p[2].i = 3.3946; p[2].idot = 2.75E-8; p[2].w = 54.8910; p[2].wdot = 1.38374E-5; p[2].a = 0.723330; p[2].adot = 0; p[2].e = 0.006773; p[2].edot = -1.302E-9; p[2].M = 48.0052; p[2].Mdot = 1.6021302244; p[3].O = 0; p[3].Odot = 0; p[3].i = 0.0; p[3].idot = 0; p[3].w = 102.9472; p[3].wdot = 4.70935E-5; p[3].a = 1.000000; p[3].adot = 0; p[3].e = 0.016709; p[3].edot = -1.151E-9; p[3].M = 356.0470; p[3].Mdot = 0.9856002585; //O=0, w= 282.9404, M = 356.0470 p[4].O = 49.5574; p[4].Odot = 2.11081E-5; p[4].i = 1.8497; p[4].idot = -1.78E-8; p[4].w = 286.5016; p[4].wdot = 2.92961E-5; p[4].a = 1.523688; p[4].adot = 0; p[4].e = 0.093405; p[4].edot = 2.516E-9; p[4].M = 18.6021; p[4].Mdot = 0.5240207766; p[5].O = 100.4542; p[5].Odot = 2.76854E-5; p[5].i = 1.3030; p[5].idot = -1.557E-7; p[5].w = 273.8777; p[5].wdot = 1.64505E-5; p[5].a = 5.20256; p[5].adot = 0; p[5].e = 0.048498; p[5].edot = 4.469E-9; p[5].M = 19.8950; p[5].Mdot = 0.0830853001; p[6].O = 113.6634; p[6].Odot = 2.38980E-5; p[6].i = 2.4886; p[6].idot = -1.081E-7; p[6].w = 339.3939; p[6].wdot = 2.97661E-5; p[6].a = 9.55475; p[6].adot = 0; p[6].e = 0.055546; p[6].edot = -9.499E-9; p[6].M = 316.9670; p[6].Mdot = 0.0334442282; p[7].O = 74.0005; p[7].Odot = 1.3978E-5; p[7].i = 0.7733; p[7].idot = 1.9E-8; p[7].w = 96.6612; p[7].wdot = 3.0565E-5; p[7].a = 19.18171; p[7].adot = -1.55E-8; p[7].e = 0.047318; p[7].edot = 7.45E-9; p[7].M = 142.5905; p[7].Mdot = 0.011725806; p[8].O = 131.7806; p[8].Odot = 3.0173E-5; p[8].i = 1.7700; p[8].idot = -2.55E-7; p[8].w = 272.8461; p[8].wdot = -6.027E-6; p[8].a = 30.05826; p[8].adot = 3.313E-8; p[8].e = 0.008606; p[8].edot = 2.15E-9; p[8].M = 260.2471; p[8].Mdot = 0.005995147; } void getplanetphases(double *x, double *y, double *z, double *vx, double *vy, double *vz, double d, double dt) { int i; struct orbel p[9]; getplanetels(p); for (i = 1; i <= 8; i++) { calcphaseel(&x[i], &y[i], &z[i], &vx[i], &vy[i], &vz[i], &p[i], d, dt); } } /*void getmoonpos(double *x, double *y, double *z, double d) { double O, i, w, a, e, M; double xe, ye, ze; O = 125.1228 - 0.0529538083 * d i = 5.1454 w = 318.0634 + 0.1643573223 * d a = 60.2666 * 149598000.0 / 6378.137; e = 0.054900 M = 115.3654 + 13.0649929509 * d calcpos(x,y,z,O,i,w,a,e,M); getearthpos(xe,ye,ze,d); *x += *xe; *y += *ye; *z += *ze; }*/ void calcpos(double *x, double *y, double *z, double O, double i, double w, double a, double e, double M) { double E; //eccentric anomaly double v; //true anomaly double r; //perihelion distance double Eold = 0.0; double xv, yv; O *= dtor; i *= dtor; w *= dtor; M *= dtor; E = M + e * sin(M) * ( 1.0 + e * cos(M) ); if (e > 0.05) { do { Eold = E; E -= ( E - e * sin(E) - M ) / ( 1 - e * cos(E) ); } while (E - Eold >= 0.00001); } xv = a * ( cos(E) - e ); yv = a * ( sqrt(1.0 - e*e) * sin(E) ); v = atan2( yv, xv ); r = sqrt( xv*xv + yv*yv ); *x = r * (cos(O) * cos(v+w) - sin(O) * sin(v+w) * cos(i)); *y = r * (sin(O) * cos(v+w) + cos(O) * sin(v+w) * cos(i)); *z = r * (sin(v+w) * sin(i)); return; } void calcposel(double *x, double *y, double *z, struct orbel *elements, double d) { calcpos(x,y,z, elements->O + elements->Odot*d, elements->i + elements->idot*d, elements->w + elements->wdot*d, elements->a + elements->adot*d, elements->e + elements->edot*d, //why minus? who knows! elements->M + elements->Mdot*d); } void calcphaseel(double *x, double *y, double *z, double *vx, double *vy, double *vz, struct orbel *elements, double d, double dt) { //If dt = 1 timestep this will give exact answer with Euler's method for t=1... double x1,y1,z1; calcposel(x,y,z,elements,d); calcposel(&x1,&y1,&z1,elements,d+dt); *vx = (x1-*x)/dt; *vy = (y1-*y)/dt; *vz = (z1-*z)/dt; }