Time: The sun solver has been generalised to to handle any solar system body.
The functions fgSunPositionGST() and fgTimeSecondsUntilSunAngle() have been renamed to fgBodyPositionGST() and fgBodyPositionGST() respectively, and both require a new char argument specifying the body of interest. This allows the position of all solar system bodies to be calculated from the aircraft frame of reference.
This commit is contained in:
parent
0ba2e8708e
commit
6e62228c1d
4 changed files with 56 additions and 50 deletions
|
@ -363,19 +363,19 @@ void TimeManager::setTimeOffset(const std::string& offset_type, long int offset)
|
||||||
if ( offset_type == "real" ) {
|
if ( offset_type == "real" ) {
|
||||||
warp = 0;
|
warp = 0;
|
||||||
} else if ( offset_type == "dawn" ) {
|
} else if ( offset_type == "dawn" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 90.0, true );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, true, "sun" );
|
||||||
} else if ( offset_type == "morning" ) {
|
} else if ( offset_type == "morning" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 75.0, true );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, true, "sun" );
|
||||||
} else if ( offset_type == "noon" ) {
|
} else if ( offset_type == "noon" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 0.0, true );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 0.0, true, "sun" );
|
||||||
} else if ( offset_type == "afternoon" ) {
|
} else if ( offset_type == "afternoon" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 75.0, false );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, false, "sun" );
|
||||||
} else if ( offset_type == "dusk" ) {
|
} else if ( offset_type == "dusk" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 90.0, false );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, false, "sun" );
|
||||||
} else if ( offset_type == "evening" ) {
|
} else if ( offset_type == "evening" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 100.0, false );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 100.0, false, "sun" );
|
||||||
} else if ( offset_type == "midnight" ) {
|
} else if ( offset_type == "midnight" ) {
|
||||||
warp = fgTimeSecondsUntilSunAngle( cur_time, loc, 180.0, false );
|
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 180.0, false, "sun" );
|
||||||
} else if ( offset_type == "system-offset" ) {
|
} else if ( offset_type == "system-offset" ) {
|
||||||
warp = offset;
|
warp = offset;
|
||||||
orig_warp = 0;
|
orig_warp = 0;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* bodysolver.cxx - given a location on earth and a time of day/date,
|
* bodysolver.cxx - given a location on earth and a time of day/date,
|
||||||
* find the number of seconds to various sun positions.
|
* find the number of seconds to various solar system body
|
||||||
|
* positions.
|
||||||
*
|
*
|
||||||
* Written by Curtis Olson, started September 2003.
|
* Written by Curtis Olson, started September 2003.
|
||||||
*
|
*
|
||||||
|
@ -46,21 +47,22 @@ static const time_t step_secs = 60;
|
||||||
|
|
||||||
/* given a particular time expressed in side real time at prime
|
/* given a particular time expressed in side real time at prime
|
||||||
* meridian (GST), compute position on the earth (lat, lon) such that
|
* meridian (GST), compute position on the earth (lat, lon) such that
|
||||||
* sun is directly overhead. (lat, lon are reported in radians */
|
* solar system body is directly overhead. (lat, lon are reported in
|
||||||
|
* radians) */
|
||||||
|
|
||||||
void fgSunPositionGST(double gst, double *lon, double *lat) {
|
void fgBodyPositionGST(double gst, double *lon, double *lat, const char *body) {
|
||||||
/* time_t ssue; seconds since unix epoch */
|
/* time_t ssue; seconds since unix epoch */
|
||||||
/* double *lat; (return) latitude */
|
/* double *lat; (return) latitude */
|
||||||
/* double *lon; (return) longitude */
|
/* double *lon; (return) longitude */
|
||||||
|
|
||||||
double tmp;
|
double tmp;
|
||||||
|
|
||||||
SGPropertyNode* sun = fgGetNode("/ephemeris/sun");
|
SGPropertyNode* body_node = fgGetNode("/ephemeris/" + std::string(body));
|
||||||
assert(sun);
|
assert(body_node);
|
||||||
double xs = sun->getDoubleValue("xs");
|
double xs = body_node->getDoubleValue("xs");
|
||||||
//double ys = sun->getDoubleValue("ys");
|
//double ys = body_node->getDoubleValue("ys");
|
||||||
double ye = sun->getDoubleValue("ye");
|
double ye = body_node->getDoubleValue("ye");
|
||||||
double ze = sun->getDoubleValue("ze");
|
double ze = body_node->getDoubleValue("ze");
|
||||||
double ra = atan2(ye, xs);
|
double ra = atan2(ye, xs);
|
||||||
double dec = atan2(ze, sqrt(xs * xs + ye * ye));
|
double dec = atan2(ze, sqrt(xs * xs + ye * ye));
|
||||||
|
|
||||||
|
@ -73,52 +75,53 @@ void fgSunPositionGST(double gst, double *lon, double *lat) {
|
||||||
*lat = dec;
|
*lat = dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double sun_angle( const SGTime &t, const SGVec3d& world_up) {
|
static double body_angle( const SGTime &t, const SGVec3d& world_up, const char* body) {
|
||||||
SG_LOG( SG_EVENT, SG_DEBUG, " Updating Sun position" );
|
SG_LOG( SG_EVENT, SG_DEBUG, " Updating " << body << " position" );
|
||||||
SG_LOG( SG_EVENT, SG_DEBUG, " Gst = " << t.getGst() );
|
SG_LOG( SG_EVENT, SG_DEBUG, " Gst = " << t.getGst() );
|
||||||
|
|
||||||
double sun_lon, sun_gc_lat;
|
double lon, gc_lat;
|
||||||
fgSunPositionGST( t.getGst(), &sun_lon, &sun_gc_lat );
|
fgBodyPositionGST( t.getGst(), &lon, &gc_lat, body );
|
||||||
SGVec3d sunpos = SGVec3d::fromGeoc(SGGeoc::fromRadM(sun_lon, sun_gc_lat,
|
SGVec3d bodypos = SGVec3d::fromGeoc(SGGeoc::fromRadM(lon, gc_lat,
|
||||||
SGGeodesy::EQURAD));
|
SGGeodesy::EQURAD));
|
||||||
|
|
||||||
SG_LOG( SG_EVENT, SG_DEBUG, " t.cur_time = " << t.get_cur_time() );
|
SG_LOG( SG_EVENT, SG_DEBUG, " t.cur_time = " << t.get_cur_time() );
|
||||||
SG_LOG( SG_EVENT, SG_DEBUG,
|
SG_LOG( SG_EVENT, SG_DEBUG,
|
||||||
" Sun Geocentric lat = " << sun_gc_lat );
|
" " << body << " geocentric lat = " << gc_lat );
|
||||||
|
|
||||||
// calculate the sun's relative angle to local up
|
// calculate the body's relative angle to local up
|
||||||
SGVec3d nup = normalize(world_up);
|
SGVec3d nup = normalize(world_up);
|
||||||
SGVec3d nsun = normalize(sunpos);
|
SGVec3d nbody = normalize(bodypos);
|
||||||
// cout << "nup = " << nup[0] << "," << nup[1] << ","
|
// cout << "nup = " << nup[0] << "," << nup[1] << ","
|
||||||
// << nup[2] << endl;
|
// << nup[2] << endl;
|
||||||
// cout << "nsun = " << nsun[0] << "," << nsun[1] << ","
|
// cout << "nbody = " << nbody[0] << "," << nbody[1] << ","
|
||||||
// << nsun[2] << endl;
|
// << nbody[2] << endl;
|
||||||
|
|
||||||
double sun_angle = acos( dot( nup, nsun ) );
|
double body_angle = acos( dot( nup, nbody ) );
|
||||||
|
|
||||||
double signedPI = (sun_angle < 0.0) ? -SGD_PI : SGD_PI;
|
double signedPI = (body_angle < 0.0) ? -SGD_PI : SGD_PI;
|
||||||
sun_angle = fmod(sun_angle+signedPI, SGD_2PI) - signedPI;
|
body_angle = fmod(body_angle+signedPI, SGD_2PI) - signedPI;
|
||||||
|
|
||||||
double sun_angle_deg = sun_angle * SG_RADIANS_TO_DEGREES;
|
double body_angle_deg = body_angle * SG_RADIANS_TO_DEGREES;
|
||||||
SG_LOG( SG_EVENT, SG_DEBUG, "sun angle relative to current location = "
|
SG_LOG( SG_EVENT, SG_DEBUG, body << " angle relative to current location = "
|
||||||
<< sun_angle_deg );
|
<< body_angle_deg );
|
||||||
|
|
||||||
return sun_angle_deg;
|
return body_angle_deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the current unix time in seconds, calculate seconds to the
|
* Given the current unix time in seconds, calculate seconds to the
|
||||||
* specified sun angle (relative to straight up.) Also specify if we
|
* specified body angle (relative to straight up.) Also specify if we
|
||||||
* want the angle while the sun is ascending or descending. For
|
* want the angle while the body is ascending or descending. For
|
||||||
* instance noon is when the sun angle is 0 (or the closest it can
|
* instance noon is when the sun angle is 0 (or the closest it can
|
||||||
* get.) Dusk is when the sun angle is 90 and descending. Dawn is
|
* get.) Dusk is when the sun angle is 90 and descending. Dawn is
|
||||||
* when the sun angle is 90 and ascending.
|
* when the sun angle is 90 and ascending.
|
||||||
*/
|
*/
|
||||||
time_t fgTimeSecondsUntilSunAngle( time_t cur_time,
|
time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
||||||
const SGGeod& loc,
|
const SGGeod& loc,
|
||||||
double target_angle_deg,
|
double target_angle_deg,
|
||||||
bool ascending )
|
bool ascending,
|
||||||
|
const char *body )
|
||||||
{
|
{
|
||||||
SGVec3d world_up = SGVec3d::fromGeod(loc);
|
SGVec3d world_up = SGVec3d::fromGeod(loc);
|
||||||
SGTime t = SGTime( loc, SGPath(), 0 );
|
SGTime t = SGTime( loc, SGPath(), 0 );
|
||||||
|
@ -132,7 +135,7 @@ time_t fgTimeSecondsUntilSunAngle( time_t cur_time,
|
||||||
secs += step_secs )
|
secs += step_secs )
|
||||||
{
|
{
|
||||||
t.update( loc, secs, 0 );
|
t.update( loc, secs, 0 );
|
||||||
double angle_deg = sun_angle( t, world_up );
|
double angle_deg = body_angle( t, world_up, body );
|
||||||
double diff = fabs( angle_deg - target_angle_deg );
|
double diff = fabs( angle_deg - target_angle_deg );
|
||||||
if ( diff < best_diff ) {
|
if ( diff < best_diff ) {
|
||||||
if ( last_angle <= 180.0 && ascending
|
if ( last_angle <= 180.0 && ascending
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* bodysolver.hxx - given a location on earth and a time of day/date,
|
* bodysolver.hxx - given a location on earth and a time of day/date,
|
||||||
* find the number of seconds to various sun positions.
|
* find the number of seconds to various solar system body
|
||||||
|
* positions.
|
||||||
*
|
*
|
||||||
* Written by Curtis Olson, started September 2003.
|
* Written by Curtis Olson, started September 2003.
|
||||||
*
|
*
|
||||||
|
@ -24,8 +25,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SUNSOLVER_HXX
|
#ifndef _BODYSOLVER_HXX
|
||||||
#define _SUNSOLVER_HXX
|
#define _BODYSOLVER_HXX
|
||||||
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
@ -40,23 +41,25 @@ class SGGeod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the current unix time in seconds, calculate seconds to the
|
* Given the current unix time in seconds, calculate seconds to the
|
||||||
* specified sun angle (relative to straight up.) Also specify if we
|
* specified solar system body angle (relative to straight up.) Also
|
||||||
* want the angle while the sun is ascending or descending. For
|
* specify if we want the angle while the body is ascending or descending.
|
||||||
* instance noon is when the sun angle is 0 (or the closest it can
|
* For instance noon is when the sun angle is 0 (or the closest it can
|
||||||
* get.) Dusk is when the sun angle is 90 and descending. Dawn is
|
* get.) Dusk is when the sun angle is 90 and descending. Dawn is
|
||||||
* when the sun angle is 90 and ascending.
|
* when the sun angle is 90 and ascending.
|
||||||
*/
|
*/
|
||||||
time_t fgTimeSecondsUntilSunAngle( time_t cur_time,
|
time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
||||||
const SGGeod& loc,
|
const SGGeod& loc,
|
||||||
double target_angle_deg,
|
double target_angle_deg,
|
||||||
bool ascending );
|
bool ascending,
|
||||||
|
const char *body );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* given a particular time expressed in side real time at prime
|
* given a particular time expressed in side real time at prime
|
||||||
* meridian (GST), compute position on the earth (lat, lon) such that
|
* meridian (GST), compute position on the earth (lat, lon) such that
|
||||||
* sun is directly overhead. (lat, lon are reported in radians
|
* solar system body is directly overhead. (lat, lon are reported in
|
||||||
|
* radians)
|
||||||
*/
|
*/
|
||||||
void fgSunPositionGST(double gst, double *lon, double *lat);
|
void fgBodyPositionGST(double gst, double *lon, double *lat, const char *body);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SUNSOLVER_HXX */
|
#endif /* _BODYSOLVER_HXX */
|
||||||
|
|
|
@ -392,7 +392,7 @@ void FGLight::updateSunPos()
|
||||||
{
|
{
|
||||||
SGTime *t = globals->get_time_params();
|
SGTime *t = globals->get_time_params();
|
||||||
|
|
||||||
fgSunPositionGST(t->getGst(), &_sun_lon, &_sun_lat);
|
fgBodyPositionGST(t->getGst(), &_sun_lon, &_sun_lat, "sun");
|
||||||
|
|
||||||
// It might seem that sun_gc_lat needs to be converted to geodetic
|
// It might seem that sun_gc_lat needs to be converted to geodetic
|
||||||
// latitude here, but it doesn't. The sun latitude is the latitude
|
// latitude here, but it doesn't. The sun latitude is the latitude
|
||||||
|
|
Loading…
Add table
Reference in a new issue