00001 /* 00002 * CelestialBody.cpp 00003 * 00004 * Part of Fly! Legacy project 00005 * 00006 * This code was originally taken from SimGear 0.3.3; see 00007 * the end of this file for the original SimGear comments. 00008 * 00009 * Copyright 2003 Chris Wallace 00010 * 00011 * Fly! Legacy is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * Fly! Legacy is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with Fly! Legacy; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 * 00025 */ 00026 00034 #include <math.h> 00035 #include "../Include/Ephemeris.h" 00036 #include "../Include/Utility.h" 00037 00038 00039 /************************************************************************** 00040 * void CCelestialBody::updatePosition(double mjd, CSol *ourSun) 00041 * 00042 * Basically, this member function provides a general interface for 00043 * calculating the right ascension and declinaion. This function is 00044 * used for calculating the planetary positions. For the planets, an 00045 * overloaded member function is provided to additionally calculate the 00046 * planet's magnitude. 00047 * The sun and moon have their own overloaded updatePosition member, as their 00048 * position is calculated an a slightly different manner. 00049 * 00050 * arguments: 00051 * double mjd: provides the modified julian date. 00052 * CSol *ourSun: the sun's position is needed to convert heliocentric 00053 * coordinates into geocentric coordinates. 00054 * 00055 * return value: none 00056 * 00057 *************************************************************************/ 00058 void CCelestialBody::UpdatePosition(double mjd, CSol *ourSun) 00059 { 00060 double eccAnom, v, ecl, actTime, 00061 xv, yv, xh, yh, zh, xg, yg, zg, xe, ye, ze; 00062 00063 UpdateOrbElements(mjd); 00064 actTime = CalcActTime(mjd); 00065 00066 // calcualate the angle bewteen ecliptic and equatorial coordinate system 00067 ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 *actTime); 00068 00069 eccAnom = CalcEccAnom(M, e); //calculate the eccentric anomaly 00070 xv = a * (cos(eccAnom) - e); 00071 yv = a * (sqrt (1.0 - e * e) * sin(eccAnom)); 00072 v = atan2(yv, xv); // the planet's true anomaly 00073 r = sqrt (xv*xv + yv*yv); // the planet's distance 00074 00075 // calculate the planet's position in 3D space 00076 xh = r * (cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i)); 00077 yh = r * (sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i)); 00078 zh = r * (sin(v+w) * sin(i)); 00079 00080 // calculate the ecliptic longitude and latitude 00081 xg = xh + ourSun->getxs(); 00082 yg = yh + ourSun->getys(); 00083 zg = zh; 00084 00085 lonEcl = atan2(yh, xh); 00086 latEcl = atan2(zh, sqrt(xh*xh+yh*yh)); 00087 00088 xe = xg; 00089 ye = yg * cos(ecl) - zg * sin(ecl); 00090 ze = yg * sin(ecl) + zg * cos(ecl); 00091 rightAscension = atan2(ye, xe); 00092 declination = atan2(ze, sqrt(xe*xe + ye*ye)); 00093 /* SG_LOG(SG_GENERAL, SG_INFO, "Planet found at : " 00094 << rightAscension << " (ra), " << declination << " (dec)" ); */ 00095 00096 //calculate some variables specific to calculating the magnitude 00097 //of the planet 00098 R = sqrt (xg*xg + yg*yg + zg*zg); 00099 s = ourSun->getDistance(); 00100 00101 // It is possible from these calculations for the argument to acos 00102 // to exceed the valid range for acos(). So we do a little extra 00103 // checking. 00104 00105 double tmp = (r*r + R*R - s*s) / (2*r*R); 00106 if ( tmp > 1.0) { 00107 tmp = 1.0; 00108 } else if ( tmp < -1.0) { 00109 tmp = -1.0; 00110 } 00111 00112 FV = SGD_RADIANS_TO_DEGREES * acos( tmp ); 00113 } 00114 00115 /**************************************************************************** 00116 * double CCelestialBody::sgCalcEccAnom(double M, double e) 00117 * this private member calculates the eccentric anomaly of a celestial body, 00118 * given its mean anomaly and eccentricity. 00119 * 00120 * -Mean anomaly: the approximate angle between the perihelion and the current 00121 * position. this angle increases uniformly with time. 00122 * 00123 * True anomaly: the actual angle between perihelion and current position. 00124 * 00125 * Eccentric anomaly: this is an auxilary angle, used in calculating the true 00126 * anomaly from the mean anomaly. 00127 * 00128 * -eccentricity. Indicates the amount in which the orbit deviates from a 00129 * circle (0 = circle, 0-1, is ellipse, 1 = parabola, > 1 = hyperbola). 00130 * 00131 * This function is also known as solveKeplersEquation() 00132 * 00133 * arguments: 00134 * M: the mean anomaly in radians 00135 * e: the eccentricity 00136 * 00137 * return value: 00138 * the eccentric anomaly in radians 00139 * 00140 ****************************************************************************/ 00141 double CCelestialBody::CalcEccAnom(double M, double e) 00142 { 00143 double 00144 eccAnom, E0, E1, diff; 00145 00146 eccAnom = M + e * sin(M) * (1.0 + e * cos (M)); 00147 // iterate to achieve a greater precision for larger eccentricities 00148 if (e > 0.05) 00149 { 00150 E0 = eccAnom; 00151 do 00152 { 00153 E1 = E0 - (E0 - e * sin(E0) - M) / (1 - e *cos(E0)); 00154 diff = fabs(E0 - E1); 00155 E0 = E1; 00156 } 00157 while (diff > (SGD_DEGREES_TO_RADIANS * 0.001)); 00158 return E0; 00159 } 00160 return eccAnom; 00161 } 00162 00163 /***************************************************************************** 00164 * CCelestialBody::CCelestialBody are the public constructors for a generic 00165 * celestial body object. 00166 * Initializes the 6 primary orbital elements. The elements are: 00167 * N: longitude of the ascending node 00168 * i: inclination to the ecliptic 00169 * w: argument of perihelion 00170 * a: semi-major axis, or mean distance from the sun 00171 * e: eccenticity 00172 * M: mean anomaly 00173 * Each orbital element consists of a constant part and a variable part that 00174 * gradually changes over time. 00175 * 00176 * Argumetns: 00177 * the 13 arguments to the constructor constitute the first, constant 00178 * ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital 00179 * elements. The 13th argument is the current time. Note that the inclination 00180 * is written with a capital (If, Is), because 'if' is a reserved word in the 00181 * C/C++ programming language. 00182 ***************************************************************************/ 00183 CCelestialBody::CCelestialBody (double Nf, double If, double wf, 00184 double af, double ef, double Mf, 00185 double Ns, double Is, double ws, 00186 double as, double es, double Ms, 00187 double mjd) 00188 { 00189 SetElements (Nf, If, wf, af, ef, Mf, Ns, Is, ws, as, es, Ms, mjd); 00190 } 00191 00192 CCelestialBody::CCelestialBody (double Nf, double If, double wf, 00193 double af, double ef, double Mf, 00194 double Ns, double Is, double ws, 00195 double as, double es, double Ms) 00196 { 00197 SetElements (Nf, If, wf, af, ef, Mf, Ns, Is, ws, as, es, Ms); 00198 } 00199 00200 00201 /***************************************************************************** 00202 * CCelestialBody::SetElements re-initializes the orbital elements for 00203 * a celestialBody object. See constructor comments for details 00204 ***************************************************************************/ 00205 void CCelestialBody::SetElements(double Nf, double If, double wf, 00206 double af, double ef, double Mf, 00207 double Ns, double Is, double ws, 00208 double as, double es, double Ms, 00209 double mjd) 00210 { 00211 this->Nf = Nf; 00212 this->If = If; 00213 this->wf = wf; 00214 this->af = af; 00215 this->ef = ef; 00216 this->Mf = Mf; 00217 00218 this->Ns = Ns; 00219 this->Is = Is; 00220 this->ws = ws; 00221 this->as = as; 00222 this->es = es; 00223 this->Ms = Ms; 00224 00225 UpdateOrbElements(mjd); 00226 } 00227 00228 void CCelestialBody::SetElements(double Nf, double If, double wf, 00229 double af, double ef, double Mf, 00230 double Ns, double Is, double ws, 00231 double as, double es, double Ms) 00232 { 00233 this->Nf = Nf; 00234 this->If = If; 00235 this->wf = wf; 00236 this->af = af; 00237 this->ef = ef; 00238 this->Mf = Mf; 00239 00240 this->Ns = Ns; 00241 this->Is = Is; 00242 this->ws = ws; 00243 this->as = as; 00244 this->es = es; 00245 this->Ms = Ms; 00246 } 00247 00248 00249 /**************************************************************************** 00250 * void CCelestialBody::updateOrbElements(double mjd) 00251 * given the current time, this private member calculates the actual 00252 * orbital elements 00253 * 00254 * Arguments: double mjd: the current modified julian date: 00255 * 00256 * return value: none 00257 ***************************************************************************/ 00258 void CCelestialBody::UpdateOrbElements(double mjd) 00259 { 00260 double actTime = CalcActTime(mjd); 00261 00262 M = WrapTwoPi (SGD_DEGREES_TO_RADIANS * (Mf + (Ms * actTime))); 00263 w = WrapTwoPi (SGD_DEGREES_TO_RADIANS * (wf + (ws * actTime))); 00264 N = WrapTwoPi (SGD_DEGREES_TO_RADIANS * (Nf + (Ns * actTime))); 00265 i = WrapTwoPi (SGD_DEGREES_TO_RADIANS * (If + (Is * actTime))); 00266 e = ef + (es * actTime); 00267 a = af + (as * actTime); 00268 } 00269 00270 /***************************************************************************** 00271 * double CCelestialBody::CalcActTime(double mjd) 00272 * this private member function returns the offset in days from the epoch for 00273 * wich the orbital elements are calculated (Jan, 1st, 2000). 00274 * 00275 * Argument: the current time 00276 * 00277 * return value: the (fractional) number of days since Jan 1, 2000. 00278 ****************************************************************************/ 00279 double CCelestialBody::CalcActTime(double mjd) 00280 { 00281 // return (mjd - 36523.5); 00282 return (mjd - 51544); 00283 } 00284 00285 /***************************************************************************** 00286 * inline void CCelestialBody::getPos(double* ra, double* dec) 00287 * gives public access to Right Ascension and declination 00288 * 00289 ****************************************************************************/ 00290 void CCelestialBody::GetPos(double* ra, double* dec) 00291 { 00292 *ra = rightAscension; 00293 *dec = declination; 00294 } 00295 00296 /***************************************************************************** 00297 * inline void CCelestialBody::getPos(double* ra, double* dec, double* magnitude 00298 * gives public acces to the current Right ascension, declination, magnitude 00299 * and colour 00300 ****************************************************************************/ 00301 void CCelestialBody::GetPos(double* ra, double* dec, double* magn) 00302 { 00303 *ra = rightAscension; 00304 *dec = declination; 00305 *magn = magnitude; 00306 } 00307 00308 /***************************************************************************** 00309 * Public accessor methods for right ascension, declination, magnitude, 00310 * colour, latitude and longitude 00311 ****************************************************************************/ 00312 00313 double CCelestialBody::GetRightAscension() { return rightAscension; } 00314 double CCelestialBody::GetDeclination() { return declination; } 00315 double CCelestialBody::GetMagnitude() { return magnitude; } 00316 double CCelestialBody::GetLon() { return lonEcl; } 00317 double CCelestialBody::GetLat() { return latEcl; } 00318 00319 /************************************************************************** 00320 * celestialBody.cxx 00321 * Written by Durk Talsma. Originally started October 1997, for distribution 00322 * with the FlightGear project. Version 2 was written in August and 00323 * September 1998. This code is based upon algorithms and data kindly 00324 * provided by Mr. Paul Schlyter. (pausch@saaf.se). 00325 * 00326 * This library is free software; you can redistribute it and/or 00327 * modify it under the terms of the GNU Library General Public 00328 * License as published by the Free Software Foundation; either 00329 * version 2 of the License, or (at your option) any later version. 00330 * 00331 * This library is distributed in the hope that it will be useful, 00332 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00333 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00334 * Library General Public License for more details. 00335 * 00336 * You should have received a copy of the GNU Library General Public 00337 * License along with this library; if not, write to the 00338 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00339 * Boston, MA 02111-1307, USA. 00340 * 00341 **************************************************************************/
|
|
Documentation generated by
|