head 1.4; access; symbols; locks; strict; comment @# @; 1.4 date 2002.09.07.01.50.35; author curt; state Exp; branches; next 1.3; 1.3 date 2002.08.31.19.01.50; author curt; state Exp; branches; next 1.2; 1.2 date 2002.08.31.18.53.58; author curt; state Exp; branches; next 1.1; 1.1 date 2002.02.15.17.21.54; author curt; state Exp; branches; next ; desc @@ 1.4 log @Updated doxygen docs. @ text @
Main Page Class Hierarchy Compound List File List Compound Members File Members

# celestialBody.cxx

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

@ 1.3 log @Oops, try again. @ text @d278 1 a278 1