static void ecleq_aux ( int sw, /* +1 for eq to ecliptic, -1 for vv. */ double mj, double x, double y, /* sw==1: x==ra, y==dec. sw==-1: x==lg, y==lt. */ double *p, double *q) /* sw==1: p==lg, q==lt. sw==-1: p==ra, q==dec. */ { static double lastmj = -10000; /* last mj calculated */ static double seps, ceps; /* sin and cos of mean obliquity */ double sx, cx, sy, cy, ty, sq; if (mj != lastmj) { double eps; obliquity (mj, &eps); /* mean obliquity for date */ seps = sin(eps); ceps = cos(eps); lastmj = mj; } sy = sin(y); cy = cos(y); /* always non-negative */ if (fabs(cy)<1e-20) cy = 1e-20; /* insure > 0 */ ty = sy/cy; cx = cos(x); sx = sin(x); sq = (sy*ceps)-(cy*seps*sx*sw); if (sq < -1) sq = -1; if (sq > 1) sq = 1; *q = asin(sq); *p = atan(((sx*ceps)+(ty*seps*sw))/cx); if (cx<0) *p += PI; /* account for atan quad ambiguity */ range (p, 2*PI); }
int main(){ #define L 2 double ep[L] = {J2000, J1984}; for(int i=0; i < L; i++){ printf("Ep %.10f E %.10f Edot %.10f\n", ep[i], obliquity(ep[i]), obliquity_dot(ep[i])); } return 0; }
/* coordinate transformation * from: * J2000.0 rectangular equatoreal ret[{0,1,2}] = {x,y,z} * to: * mean equinox of date spherical ecliptical ret[{0,1,2}] = {l,b,r} */ static void chap_trans ( double mj, /* destination epoch */ double *ret) /* vector to be transformed _IN PLACE_ */ { double ra, dec, r, eps; double sr, cr, sd, cd, se, ce; cartsph(ret[0], ret[1], ret[2], &ra, &dec, &r); precess(J2000, mj, &ra, &dec); obliquity(mj, &eps); sr = sin(ra); cr = cos(ra); sd = sin(dec); cd = cos(dec); se = sin(eps); ce = cos(eps); ret[0] = atan2( sr * ce + sd/cd * se, cr); /* long */ ret[1] = asin( sd * ce - cd * se * sr); /* lat */ ret[2] = r; /* radius */ }
/* given a Now *, find the local apparent sidereal time, in hours. */ void now_lst (Now *np, double *lstp) { static double last_mjd = -23243, last_lng = 121212, last_lst; double eps, lst, deps, dpsi; if (last_mjd == mjd && last_lng == lng) { *lstp = last_lst; return; } utc_gst (mjd_day(mjd), mjd_hr(mjd), &lst); lst += radhr(lng); obliquity(mjd, &eps); nutation(mjd, &deps, &dpsi); lst += radhr(dpsi*cos(eps+deps)); range (&lst, 24.0); last_mjd = mjd; last_lng = lng; *lstp = last_lst = lst; }
bool Ephemeris::computeEphemeris(int &sunriseHours, int &sunriseMinutes, int &sunsetHours, int &sunsetMinutes) { double DJJ = dateToJulianDate(); double LS = longitudeSun(DJJ); LS = LS+(-993.0+17.0*cos(3.10+62830.14*((((DJJ-2451545.0)/3652500.0)-2451545.0)/3652500.0)))*pow(10,-7); LS = LS+(-834.0*sin(2.18-3375.7*(((DJJ-2451545.0)/3652500.0))+0.36*pow(((DJJ-2451545.0)/3652500.0),2))-64.0* sin(3.51-125666.39*((DJJ-2451545.0)/3652500.0)+0.10*pow(((DJJ-2451545.0)/3652500.0),2)))*pow(10,-7); double obliq = obliquity(DJJ); double alpS = atan2((cos(obliq)*sin(LS)),(cos(LS))); double delS = asin(sin(obliq)*sin(LS)); double height = mSunElevation*mPI/180.0; double lat=mStationLatitude*mPI/180.0; double HO = acos((sin(height)-sin(lat)*sin(delS))/(cos(lat)*cos(delS))); // Check. if((((height-sin(lat)*sin(delS))/(cos(lat)*cos(delS))) < -1) || (((height-sin(lat)*sin(delS))/(cos(lat)*cos(delS)))>1)){ return false; }else{ //!******************************************************! //! Compute sunset time //!******************************************************! double TC = alpS + HO; // Compute sideral time at 0h double DJ0 = DJJ-0.5; // Julian date at 0h TU double TS0 = 1.75337+6.2833197*(DJ0-2451545.0)/365.25; double TSC = TC-TS0; TSC = fmod((fmod(TSC,2*mPI)+2*mPI),2*mPI); double longg = mStationLongitude*mPI/180.0; double TSC_TU = (TSC+longg)*0.9972696; // Sunset time in decimal hours. TSC_TU = TSC_TU*12.0/mPI; double t1; modf(TSC_TU,&t1); sunsetHours = int(t1); sunsetMinutes = int((TSC_TU - double(t1))*60.0); //!******************************************************! //! Compute sunrise time //!******************************************************! DJJ = DJJ+1.0; //! Compute sun longitude in radians. LS = longitudeSun(DJJ); LS = LS+(-993.0+17.0*cos(3.10+62830.14*((DJJ-2451545.0)/3652500.0)))*pow(10,-7); double DJJtemp=(DJJ-2451545.0)/3652500.0; LS = LS+(-834.0*sin(2.18-3375.7*(DJJtemp)+0.36*pow(DJJtemp,2))-64.0*sin(3.51-125666.39*(DJJtemp)+0.10*pow(DJJtemp,2)))*pow(10,-7); //! Compute sun right ascension and delination in radians. obliq = obliquity(DJJ); alpS = atan2((cos(obliq)*sin(LS)),(cos(LS))); delS = asin(sin(obliq)*sin(LS)); //! Compute sun hour angle. height = mSunElevation*mPI/180.0; lat = mStationLatitude*mPI/180.0; HO = acos((sin(height)-sin(lat)*sin(delS))/(cos(lat)*cos(delS))); // Check. if((((height-sin(lat)*sin(delS))/(cos(lat)*cos(delS)))<-1)||(((height-sin(lat)*sin(delS))/(cos(lat)*cos(delS)))>1)){ return false; }else { double TL = alpS-HO; // Compute sideral time at 0h DJ0 = DJJ-0.5; // Julian date at 0h TU TS0 = 1.75337+6.2833197*(DJ0-2451545.0)/365.25; double TSL = TL-TS0; TSL = fmod((fmod(TSL,2*mPI)+2*mPI),2*mPI); longg = mStationLongitude*mPI/180.0; double TSL_TU = (TSL+longg)*0.99726960; TSL_TU = TSL_TU*12.0/mPI; double t3; modf(TSL_TU,&t3); sunriseHours = int(t3); sunriseMinutes = int((TSL_TU - double(t3))*60.0); } } return true; }
bool TestAstroCoordTransformations( ) { bool ok = true; cout << "Testing AstroCoordTransformations" << endl; int h = 7; int m = 45; double s = 18.946; cout << "raPollux: AngleHMS( " << h << ", " << m << ", " << s << " )" << endl; Angle raPollux( AngleHMS( h, m, s ) ); int d = 28; m = 1; s = 34.26; cout << "decPollux: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle decPollux( AngleDMS( d, m, s ) ); Equatorial equatPollux( raPollux, decPollux ); TESTCHECKF( equatPollux.RightAscension().Degrees(), 116.328942, &ok ); TESTCHECKF( equatPollux.Declination().Degrees(), 28.026183, &ok ); TESTCHECKF( equatPollux.Distance(), 1., &ok ); double obl = 23.4392911; cout << "obliquity: " << obl << endl; Angle obliquity( obl, Angle::Degree ); cout << "EquatorialToEcliptical( equatPollux, " << obl << " )" << endl; Ecliptical ecliptPollux = EquatorialToEcliptical( equatPollux, obliquity ); TESTCHECKF( ecliptPollux.Longitude().Degrees(), 113.21562958, &ok ); TESTCHECKF( ecliptPollux.Latitude().Degrees(), 6.6841698, &ok ); TESTCHECKF( ecliptPollux.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Point3D equatPolluxV = equatPollux.Rectangular(); Matrix3D equat2eclipt = EquatorialToEclipticalMatrix( obliquity ); Point3D ecliptPolluxV = equat2eclipt * equatPolluxV; ecliptPollux.Set( ecliptPolluxV ); TESTCHECKF( ecliptPollux.Longitude().Degrees(), 113.215630, &ok ); TESTCHECKF( ecliptPollux.Latitude().Degrees(), 6.684170, &ok ); TESTCHECKF( ecliptPollux.Distance(), 1., &ok ); TESTCHECKF( EclipticalLongitude( equatPolluxV, obliquity ).Degrees(), 113.215630, &ok ); cout << "EclipticalToEquatorial( ecliptPollux, " << obl << " )" << endl; equatPollux = EclipticalToEquatorial( ecliptPollux, obliquity ); TESTCHECKF( equatPollux.RightAscension().Degrees(), 116.328942, &ok ); TESTCHECKF( equatPollux.Declination().Degrees(), 28.026183, &ok ); TESTCHECKF( equatPollux.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Matrix3D eclipt2equat = EclipticalToEquatorialMatrix( obliquity ); equatPolluxV = eclipt2equat * ecliptPolluxV; equatPollux.Set( equatPolluxV ); TESTCHECKF( equatPollux.RightAscension().Degrees(), 116.328942, &ok ); TESTCHECKF( equatPollux.Declination().Degrees(), 28.026183, &ok ); TESTCHECKF( equatPollux.Distance(), 1., &ok ); h = 23; m = 9; s = 16.641; cout << "raVenus: AngleHMS( " << h << ", " << m << ", " << s << " )" << endl; Angle raVenus( AngleHMS( h, m, s ) ); d = -6; m = 43; s = 11.61; cout << "decVenus: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle decVenus( AngleDMS( d, m, s ) ); Equatorial equatVenus( raVenus, decVenus ); TESTCHECKF( equatVenus.RightAscension().Degrees(), 347.3193375, &ok ); TESTCHECKF( equatVenus.Declination().Degrees(), -6.71988889, &ok ); TESTCHECKF( equatVenus.Distance(), 1., &ok ); h = 3; m = 26; s = 41.153; cout << "local sidereal time: " << h << "h" << m << "m" << s << "s" << endl; AngleHMS lstHMS( h, m, s ); Angle lst( lstHMS ); d = 38; m = 55; s = 17; cout << "lat U.S.N.O.: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle latUSNO( AngleDMS( d, m, s ) ); cout << "EquatorialToHorizontal( equatVenus, lst, latUSNO )" << endl; Horizontal horizVenus = EquatorialToHorizontal( equatVenus, lst, latUSNO ); TESTCHECKF( horizVenus.Azimuth().Degrees(), 248.03369608, &ok ); TESTCHECKF( horizVenus.Altitude().Degrees(), 15.12487568, &ok ); TESTCHECKF( horizVenus.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Point3D equatVenusV = equatVenus.Rectangular(); Matrix3D equat2horiz = EquatorialToHorizontalMatrix( lst, latUSNO ); Point3D horizVenusV = equat2horiz * equatVenusV; horizVenus.Set( horizVenusV ); TESTCHECKF( horizVenus.Azimuth().Degrees(), 248.03369608, &ok ); TESTCHECKF( horizVenus.Altitude().Degrees(), 15.12487568, &ok ); TESTCHECKF( horizVenus.Distance(), 1., &ok ); cout << "HorizontalToEquatorial( horizVenus, lst, latUSNO )" << endl; equatVenus = HorizontalToEquatorial( horizVenus, lst, latUSNO ); TESTCHECKF( equatVenus.RightAscension().Degrees(), 347.3193375, &ok ); TESTCHECKF( equatVenus.Declination().Degrees(), -6.71988889, &ok ); TESTCHECKF( equatVenus.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; horizVenusV = horizVenus.Rectangular(); Matrix3D horiz2equat = HorizontalToEquatorialMatrix( lst, latUSNO ); equatVenusV = horiz2equat * horizVenusV; equatVenus.Set( equatVenusV ); TESTCHECKF( equatVenus.RightAscension().Degrees(), 347.3193375, &ok ); TESTCHECKF( equatVenus.Declination().Degrees(), -6.71988889, &ok ); TESTCHECKF( equatVenus.Distance(), 1., &ok ); h = 17; m = 48; s = 59.74; cout << "raNovaSer: AngleHMS( " << h << ", " << m << ", " << s << " )" << endl; Angle raNovaSer( AngleHMS( h, m, s ) ); d = -14; m = 43; s = 8.2; cout << "decNovaSer: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle decNovaSer( AngleDMS( d, m, s ) ); Equatorial equatNovaSer( raNovaSer, decNovaSer ); TESTCHECKF( equatNovaSer.RightAscension().Degrees(), 267.248917, &ok ); TESTCHECKF( equatNovaSer.Declination().Degrees(), -14.7189444, &ok ); cout << "EquatorialToGalactic( equatNovaSer )" << endl; Galactic galNovaSer = EquatorialToGalactic( equatNovaSer ); TESTCHECKF( galNovaSer.Longitude().Degrees(), 12.95925004, &ok ); TESTCHECKF( galNovaSer.Latitude().Degrees(), 6.0462985, &ok ); TESTCHECKF( galNovaSer.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Point3D equatNovaSerV = equatNovaSer.Rectangular(); Matrix3D equat2gal = EquatorialToGalacticMatrix( ); Point3D galNovaSerV = equat2gal * equatNovaSerV; galNovaSer.Set( galNovaSerV ); TESTCHECKF( galNovaSer.Longitude().Degrees(), 12.95925004, &ok ); TESTCHECKF( galNovaSer.Latitude().Degrees(), 6.0462985, &ok ); TESTCHECKF( galNovaSer.Distance(), 1., &ok ); cout << "GalacticToEquatorial( galNovaSer )" << endl; equatNovaSer = GalacticToEquatorial( galNovaSer ); TESTCHECKF( equatNovaSer.RightAscension().Degrees(), 267.248917, &ok ); TESTCHECKF( equatNovaSer.Declination().Degrees(), -14.7189444, &ok ); TESTCHECKF( equatNovaSer.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; galNovaSerV = galNovaSer.Rectangular(); Matrix3D gal2equat = GalacticToEquatorialMatrix( ); equatNovaSerV = gal2equat * galNovaSerV; equatNovaSer.Set( equatNovaSerV ); TESTCHECKF( equatNovaSer.RightAscension().Degrees(), 267.248917, &ok ); TESTCHECKF( equatNovaSer.Declination().Degrees(), -14.7189444, &ok ); TESTCHECKF( equatNovaSer.Distance(), 1., &ok ); h = 16; m = 26; s = 29.19; cout << "raTest1: AngleHMS( " << h << ", " << m << ", " << s << " )" << endl; Angle raTest1( AngleHMS( h, m, s ) ); d = -21; m = 13; s = 38.68; cout << "decTest1: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle decTest1( AngleDMS( d, m, s ) ); Equatorial equatTest1( raTest1, decTest1 ); h = 1; m = 14; s = 45.2959; cout << "local sidereal time: " << h << "h" << m << "m" << s << "s" << endl; lstHMS.Set( h, m, s ); lst.Set( lstHMS ); d = 35; m = 43; s = 59; cout << "lat: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle latTest1( AngleDMS( d, m, s ) ); cout << "EquatorialToHorizontal( equatTest1, lst, latTest1 )" << endl; Horizontal horizTest1 = EquatorialToHorizontal( equatTest1, lst, latTest1 ); AngleDMS dmsTest1Az( horizTest1.Azimuth() ); TESTCHECK( dmsTest1Az.Positive(), true, &ok ); TESTCHECK( dmsTest1Az.Degrees(), 275, &ok ); TESTCHECK( dmsTest1Az.Minutes(), 50, &ok ); TESTCHECKFE( dmsTest1Az.Seconds(), 38.9193, &ok, 1e-3 ); AngleDMS dmsTest1Alt( horizTest1.Altitude() ); TESTCHECK( dmsTest1Alt.Positive(), false, &ok ); TESTCHECK( dmsTest1Alt.Degrees(), 45, &ok ); TESTCHECK( dmsTest1Alt.Minutes(), 55, &ok ); TESTCHECKFE( dmsTest1Alt.Seconds(), 27.7358, &ok, 1e-3 ); TESTCHECKF( horizTest1.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Point3D equatTest1V = equatTest1.Rectangular(); equat2horiz = EquatorialToHorizontalMatrix( lst, latTest1 ); Point3D horizTest1V = equat2horiz * equatTest1V; horizTest1.Set( horizTest1V ); dmsTest1Az.Set( horizTest1.Azimuth() ); TESTCHECK( dmsTest1Az.Positive(), true, &ok ); TESTCHECK( dmsTest1Az.Degrees(), 275, &ok ); TESTCHECK( dmsTest1Az.Minutes(), 50, &ok ); TESTCHECKFE( dmsTest1Az.Seconds(), 38.9193, &ok, 1e-3 ); dmsTest1Alt.Set( horizTest1.Altitude() ); TESTCHECK( dmsTest1Alt.Positive(), false, &ok ); TESTCHECK( dmsTest1Alt.Degrees(), 45, &ok ); TESTCHECK( dmsTest1Alt.Minutes(), 55, &ok ); TESTCHECKFE( dmsTest1Alt.Seconds(), 27.7358, &ok, 1e-3 ); TESTCHECKF( horizTest1.Distance(), 1., &ok ); cout << "HorizontalToEquatorial( horizTest1, lst, latTest1 )" << endl; equatTest1 = HorizontalToEquatorial( horizTest1, lst, latTest1 ); AngleHMS hmsTest1RA( equatTest1.RightAscension() ); TESTCHECK( hmsTest1RA.Hours(), 16, &ok ); TESTCHECK( hmsTest1RA.Minutes(), 26, &ok ); TESTCHECKFE( hmsTest1RA.Seconds(), 29.19, &ok, 1e-3 ); AngleDMS dmsTest1Dec( equatTest1.Declination() ); TESTCHECK( dmsTest1Dec.Positive(), false, &ok ); TESTCHECK( dmsTest1Dec.Degrees(), 21, &ok ); TESTCHECK( dmsTest1Dec.Minutes(), 13, &ok ); TESTCHECKFE( dmsTest1Dec.Seconds(), 38.68, &ok, 1e-3 ); TESTCHECKF( equatTest1.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; horizTest1V = horizTest1.Rectangular(); horiz2equat = HorizontalToEquatorialMatrix( lst, latTest1 ); equatTest1V = horiz2equat * horizTest1V; equatTest1.Set( equatTest1V ); hmsTest1RA.Set( equatTest1.RightAscension() ); TESTCHECK( hmsTest1RA.Hours(), 16, &ok ); TESTCHECK( hmsTest1RA.Minutes(), 26, &ok ); TESTCHECKFE( hmsTest1RA.Seconds(), 29.19, &ok, 1e-3 ); dmsTest1Dec.Set( equatTest1.Declination() ); TESTCHECK( dmsTest1Dec.Positive(), false, &ok ); TESTCHECK( dmsTest1Dec.Degrees(), 21, &ok ); TESTCHECK( dmsTest1Dec.Minutes(), 13, &ok ); TESTCHECKF( dmsTest1Dec.Seconds(), 38.68, &ok ); TESTCHECKFE( equatTest1.Distance(), 1., &ok, 1e-3 ); h = 16; m = 26; s = 29.399; cout << "raTest2: AngleHMS( " << h << ", " << m << ", " << s << " )" << endl; Angle raTest2( AngleHMS( h, m, s ) ); d = -21; m = 13; s = 38.39; cout << "decTest2: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; Angle decTest2( AngleDMS( d, m, s ) ); Equatorial equatTest2( raTest2, decTest2 ); d = 23; m = 26; s = 15.791; cout << "obliquity: AngleDMS( " << d << ", " << m << ", " << s << " )" << endl; obliquity.Set( AngleDMS( d, m, s ) ); cout << "EquatorialToEcliptical( equatTest2, obliquity )" << endl; Ecliptical ecliptTest2 = EquatorialToEcliptical( equatTest2, obliquity ); AngleDMS dmsTest2Long( ecliptTest2.Longitude() ); TESTCHECK( dmsTest2Long.Positive(), true, &ok ); TESTCHECK( dmsTest2Long.Degrees(), 248, &ok ); TESTCHECK( dmsTest2Long.Minutes(), 17, &ok ); TESTCHECKFE( dmsTest2Long.Seconds(), 30.82, &ok, 1e-3 ); AngleDMS dmsTest2Lat( ecliptTest2.Latitude() ); TESTCHECK( dmsTest2Lat.Positive(), true, &ok ); TESTCHECK( dmsTest2Lat.Degrees(), 0, &ok ); TESTCHECK( dmsTest2Lat.Minutes(), 27, &ok ); TESTCHECKFE( dmsTest2Lat.Seconds(), 57.59, &ok, 1e-3 ); TESTCHECKF( ecliptTest2.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; Point3D equatTest2V = equatTest2.Rectangular(); equat2eclipt = EquatorialToEclipticalMatrix( obliquity ); Point3D ecliptTest2V = equat2eclipt * equatTest2V; ecliptTest2.Set( ecliptTest2V ); dmsTest2Long.Set( ecliptTest2.Longitude() ); TESTCHECK( dmsTest2Long.Positive(), true, &ok ); TESTCHECK( dmsTest2Long.Degrees(), 248, &ok ); TESTCHECK( dmsTest2Long.Minutes(), 17, &ok ); TESTCHECKFE( dmsTest2Long.Seconds(), 30.82, &ok, 1e-3 ); dmsTest2Lat.Set( ecliptTest2.Latitude() ); TESTCHECK( dmsTest2Lat.Positive(), true, &ok ); TESTCHECK( dmsTest2Lat.Degrees(), 0, &ok ); TESTCHECK( dmsTest2Lat.Minutes(), 27, &ok ); TESTCHECKFE( dmsTest2Lat.Seconds(), 57.59, &ok, 1e-3 ); TESTCHECKF( ecliptTest2.Distance(), 1., &ok ); cout << "EclipticalToEquatorial( ecliptTest2, obliquity )" << endl; equatTest2 = EclipticalToEquatorial( ecliptTest2, obliquity ); AngleHMS hmsTest2RA( equatTest2.RightAscension() ); TESTCHECK( hmsTest2RA.Hours(), 16, &ok ); TESTCHECK( hmsTest2RA.Minutes(), 26, &ok ); TESTCHECKFE( hmsTest2RA.Seconds(), 29.399, &ok, 1e-3 ); AngleDMS dmsTest2Dec( equatTest2.Declination() ); TESTCHECK( dmsTest2Dec.Positive(), false, &ok ); TESTCHECK( dmsTest2Dec.Degrees(), 21, &ok ); TESTCHECK( dmsTest2Dec.Minutes(), 13, &ok ); TESTCHECKFE( dmsTest2Dec.Seconds(), 38.39, &ok, 1e-3 ); TESTCHECKF( equatTest2.Distance(), 1., &ok ); cout << "Same test, using points and matrices" << endl; ecliptTest2V = ecliptTest2.Rectangular(); eclipt2equat = EclipticalToEquatorialMatrix( obliquity ); equatTest2V = eclipt2equat * ecliptTest2V; equatTest2.Set( equatTest2V ); hmsTest2RA.Set( equatTest2.RightAscension() ); TESTCHECK( hmsTest2RA.Hours(), 16, &ok ); TESTCHECK( hmsTest2RA.Minutes(), 26, &ok ); TESTCHECKFE( hmsTest2RA.Seconds(), 29.399, &ok, 1e-3 ); dmsTest2Dec.Set( equatTest2.Declination() ); TESTCHECK( dmsTest2Dec.Positive(), false, &ok ); TESTCHECK( dmsTest2Dec.Degrees(), 21, &ok ); TESTCHECK( dmsTest2Dec.Minutes(), 13, &ok ); TESTCHECKF( dmsTest2Dec.Seconds(), 38.39, &ok ); TESTCHECKFE( equatTest2.Distance(), 1., &ok, 1e-3 ); if ( ok ) cout << "AstroCoordTransformations PASSED." << endl << endl; else cout << "AstroCoordTransformations FAILED." << endl << endl; return ok; }
/* given the modified JD, mj, correct, IN PLACE, the right ascension *ra * and declination *dec (both in radians) for nutation. */ void nut_eq (double mj, double *ra, double *dec) { static double lastmj = -10000; static double a[3][3]; /* rotation matrix */ double xold, yold, zold, x, y, z; if (mj != lastmj) { double epsilon, dpsi, deps; double se, ce, sp, cp, sede, cede; obliquity(mj, &epsilon); nutation(mj, &deps, &dpsi); /* the rotation matrix a applies the nutation correction to * a vector of equatoreal coordinates Xeq to Xeq' by 3 subsequent * rotations: R1 - from equatoreal to ecliptic system by * rotation of angle epsilon about x, R2 - rotate ecliptic * system by -dpsi about its z, R3 - from ecliptic to equatoreal * by rotation of angle -(epsilon + deps) * * Xeq' = A * Xeq = R3 * R2 * R1 * Xeq * * [ 1 0 0 ] * R1 = [ 0 cos(eps) sin(eps) ] * [ 0 - sin(eps) cos(eps) ] * * [ cos(dpsi) - sin(dpsi) 0 ] * R2 = [ sin(dpsi) cos(dpsi) 0 ] * [ 0 0 1 ] * * [ 1 0 0 ] * R3 = [ 0 cos(eps + deps) - sin(eps + deps) ] * [ 0 sin(eps + deps) cos(eps + deps) ] * * for efficiency, here is a explicitely: */ se = sin(epsilon); ce = cos(epsilon); sp = sin(dpsi); cp = cos(dpsi); sede = sin(epsilon + deps); cede = cos(epsilon + deps); a[0][0] = cp; a[0][1] = -sp*ce; a[0][2] = -sp*se; a[1][0] = cede*sp; a[1][1] = cede*cp*ce+sede*se; a[1][2] = cede*cp*se-sede*ce; a[2][0] = sede*sp; a[2][1] = sede*cp*ce-cede*se; a[2][2] = sede*cp*se+cede*ce; lastmj = mj; } sphcart(*ra, *dec, 1.0, &xold, &yold, &zold); x = a[0][0] * xold + a[0][1] * yold + a[0][2] * zold; y = a[1][0] * xold + a[1][1] * yold + a[1][2] * zold; z = a[2][0] * xold + a[2][1] * yold + a[2][2] * zold; cartsph(x, y, z, ra, dec, &zold); /* radius should be 1.0 */ if (*ra < 0.) *ra += 2.*PI; /* make positive for display */ }