sgp4/Eci.cpp

83 lines
2.2 KiB
C++
Raw Normal View History

2011-03-30 16:03:52 +00:00
#include "Eci.h"
#include "Util.h"
2011-12-13 22:37:13 +00:00
void Eci::ToEci(const Julian& date, const CoordGeodetic &g)
{
/*
* set date
*/
date_ = date;
2011-03-30 16:03:52 +00:00
2011-05-20 21:09:23 +00:00
static const double mfactor = kTWOPI * (kOMEGA_E / kSECONDS_PER_DAY);
2011-03-30 16:03:52 +00:00
/*
* Calculate Local Mean Sidereal Time for observers longitude
*/
2011-12-13 22:37:13 +00:00
const double theta = date_.ToLocalMeanSiderealTime(g.longitude);
2011-03-30 16:03:52 +00:00
2011-04-09 18:56:35 +00:00
/*
* take into account earth flattening
*/
2011-12-14 11:48:22 +00:00
const double c = 1.0
/ sqrt(1.0 + kF * (kF - 2.0) * pow(sin(g.latitude), 2.0));
2011-05-20 21:09:23 +00:00
const double s = pow(1.0 - kF, 2.0) * c;
2011-12-13 22:37:13 +00:00
const double achcp = (kXKMPER * c + g.altitude) * cos(g.latitude);
2011-03-30 16:03:52 +00:00
2011-04-09 18:56:35 +00:00
/*
* X position in km
* Y position in km
* Z position in km
* W magnitude in km
*/
2011-05-26 23:22:38 +00:00
position_.x = achcp * cos(theta);
position_.y = achcp * sin(theta);
2011-12-13 22:37:13 +00:00
position_.z = (kXKMPER * s + g.altitude) * sin(g.latitude);
2011-05-26 23:22:38 +00:00
position_.w = position_.GetMagnitude();
2011-03-30 16:03:52 +00:00
2011-04-09 18:56:35 +00:00
/*
* X velocity in km/s
* Y velocity in km/s
* Z velocity in km/s
* W magnitude in km/s
*/
2011-05-26 23:22:38 +00:00
velocity_.x = -mfactor * position_.y;
velocity_.y = mfactor * position_.x;
velocity_.z = 0.0;
velocity_.w = velocity_.GetMagnitude();
2011-03-30 16:03:52 +00:00
}
2011-12-13 22:37:13 +00:00
CoordGeodetic Eci::ToGeodetic() const
{
const double theta = Util::AcTan(position_.y, position_.x);
// 0 >= lon < 360
// const double lon = Fmod2p(theta - date_.ToGreenwichSiderealTime());
// 180 >= lon < 180
const double lon = fmod(theta - date_.ToGreenwichSiderealTime(), kPI);
2011-12-14 11:48:22 +00:00
const double r = sqrt((position_.x * position_.x)
+ (position_.y * position_.y));
2011-12-13 22:37:13 +00:00
2011-05-20 21:09:23 +00:00
static const double e2 = kF * (2.0 - kF);
double lat = Util::AcTan(position_.z, r);
double phi = 0.0;
double c = 0.0;
int cnt = 0;
2011-12-13 22:37:13 +00:00
do
{
phi = lat;
const double sinphi = sin(phi);
2011-04-09 23:29:46 +00:00
c = 1.0 / sqrt(1.0 - e2 * sinphi * sinphi);
lat = Util::AcTan(position_.z + kXKMPER * c * e2 * sinphi, r);
cnt++;
2011-12-13 22:37:13 +00:00
}
while (fabs(lat - phi) >= 1e-10 && cnt < 10);
2011-05-20 21:09:23 +00:00
const double alt = r / cos(lat) - kXKMPER * c;
2011-12-14 10:58:01 +00:00
return CoordGeodetic(lat, lon, alt, true);
}