00001
00002
00003
00004
00005
00006
00007
00008 #include <math.h>
00009 #include <timeio.h>
00010
00011 #define EPS 3.e-17
00012 #define OMEGA_0 (75.76) // degrees, solar equator crosses ecliptic, pre 2007 value with no aberration correction
00013 #define OMEGA_1 (0.01397) // degrees per Julian year (365.2500d) precession
00014 #define SUN_INCLINATION (7.25) // Carrington solar inclination to ecliptic
00015 #define SININCL (0.126198969135829761)
00016 #define COSINCL (0.992004949679714999)
00017
00018 #define C (299792.458) // c in km/s
00019 #define AU (149597870.69) // AU in km
00020 #define T2000 (725760032.0) // sscan_time("2000.01.01_00") J2000 base time
00021 #define TCARR (-3881476800.0) // sscan_time("1854.01.01_12:00_TAI") Carr ref epcoh est.
00022 #define CARR_DEGDAY (14.1844000) // Adopted degrees per day, includes precession
00023 #define CARR_ROT_SYNODIC (27.275311 * 86400.0) // estimate of synodic carrington rotation period
00024
00025 #define PI (3.141592653589793)
00026 #define TWO_PI (2*PI)
00027 #define DEGRAD (180.0/PI)
00028 #define SID (86400.0)
00029
00030 static double ecanom(double e, double manom);
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 void HeliographicLocation(TIME t, int *crot, double *L, double *B)
00045 {
00046 static int firstcall = 1;
00047 static TIME t1900 = 0.0;
00048 static TIME t1950 = 0;
00049 static TIME t2000 = 0;
00050
00051 double tc19, tc1950, tc20, e, eps, perigee, lo, g, ge, v, se_long;
00052 double r, Omega, se_long_Omega, xs, xc, sinB, sunB0, hci_long;
00053 double solrots;
00054 double carr_rots;
00055 double l;
00056 double tlight;
00057 double clest;
00058 int rot;
00059
00060
00061 if (firstcall)
00062 {
00063 t1900 = sscan_time("1900.01.01_UTC");
00064 t1950 = sscan_time("JD_2433282.423459");
00065 t2000 = sscan_time("2000.01.01_00:00_UTC");
00066 }
00067 if (isnan(t) || t < 0) return;
00068 tc19 = (t - t1900)/(SID*36525.0);
00069 tc20 = (t - t2000)/(SID*36525.0);
00070 tc1950 = (t - t1950)/(SID*36525.0);
00071
00072 e = 0.01673011 - tc1950*(4.193e-5 + tc1950*1.26e-7);
00073
00074 eps = 0.40920619245 - tc1950*(2.27132786e-4 + tc1950*(1.5466e-8 - tc1950*8.77516e-9));
00075
00076 perigee=4.9232342127 + tc1950*( 3.0013215e-2 + tc1950*( 7.999426e-6 + tc1950*5.8178e-8));
00077
00078 lo = 4.8815279341118791 + tc19*(628.33195094248177 + tc19*5.2796209873e-6);
00079
00080 g = lo - perigee;
00081
00082 ge = ecanom(e, g);
00083
00084 v = 2.0*atan(sqrt((1.0+e)/(1.0-e))*tan(0.5*ge));
00085
00086 se_long = v + perigee;
00087 if(se_long > TWO_PI)se_long -= TWO_PI;
00088 else if (se_long < 0)se_long += TWO_PI;
00089
00090
00091 r=(1.0-e*e)/(1.0+e*cos(se_long-perigee));
00092
00093 Omega = (OMEGA_0 + OMEGA_1*tc20*100.0)/DEGRAD;
00094
00095 se_long_Omega = se_long - Omega + PI;
00096 if (se_long_Omega > TWO_PI) se_long_Omega -= TWO_PI;
00097 else if (se_long_Omega < 0.0) se_long_Omega += TWO_PI;
00098 xs = sin(se_long_Omega);
00099 xc = cos(se_long_Omega);
00100 sinB = -xs * SININCL;
00101 sunB0 = asin(sinB);
00102
00103 hci_long = atan2(xs*COSINCL, xc);
00104 if (hci_long < 0) hci_long += TWO_PI;
00105
00106 tlight = r*AU/C;
00107 solrots = (CARR_DEGDAY * (t - tlight - TCARR)/86400.0 -0.125)/DEGRAD;
00108 l = hci_long - solrots;
00109 l = modf(l/TWO_PI, &carr_rots);
00110 if(l < 0) l += 1;
00111
00112
00113
00114 carr_rots = 3.0 + (t - tlight - TCARR)/CARR_ROT_SYNODIC;
00115 rot = carr_rots;
00116 clest = (1 + rot - carr_rots);
00117 if ((l - clest) > 0.5)
00118 rot++;
00119 if ((clest - l) > 0.5)
00120 rot--;
00121
00122 if (crot) *crot = rot;
00123 if (L) *L = 360*l;
00124 if (B) *B = sunB0 * DEGRAD;
00125 return;
00126 }
00127
00128
00129
00130
00131
00132 #define C1 0.0757646111
00133 #define T1853 "1853.11.09_22:27:24_UTC"
00134
00135
00136 TIME HeliographicTime(int crot, double L)
00137 {
00138 static TIME t1853=0.0;
00139 double i, b, l;
00140 int rot;
00141 double CThave, CTgot, clong;
00142 double err, CTp50m, CTm50m;
00143 TIME t;
00144 if (t1853 == 0.0) t1853 = sscan_time(T1853);
00145 CThave = 360.0 * crot - L;
00146 t = (t1853 + CThave*C1*SID);
00147 HeliographicLocation(t, &rot, &l, &b);
00148 CTgot = 360.0 * rot - l;
00149 err = CThave - CTgot;
00150 HeliographicLocation(t+3000.0, &rot, &l, &b);
00151 CTp50m = 360.0 * rot - l;
00152 HeliographicLocation(t-3000.0, &rot, &l, &b);
00153 CTm50m = 360.0 * rot - l;
00154 t += 6000 * (err/(CTp50m - CTm50m));
00155 return(t);
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 double ecanom(double e, double manom)
00171 {
00172 double ecm_new, ecm_old;
00173 ecm_old = manom + e*sin(manom);
00174 while (1)
00175 {
00176 ecm_new = ecm_old - (ecm_old - manom - e * sin( ecm_old))/ (1 - e * cos( ecm_old));
00177 if(fabs((ecm_new - ecm_old)/(ecm_new + ecm_old)) < EPS || fabs((ecm_new - ecm_old)) < EPS )
00178 break;
00179 ecm_old = ecm_new;
00180 }
00181 return(ecm_new);
00182 }
00183
00184