60 std::string body = sun_not_moon ?
"sun" :
"moon";
61 SGPropertyNode* body_node =
fgGetNode(
"/ephemeris/" + body);
63 double xs = sun_not_moon ? body_node->getDoubleValue(
"xs")
64 : body_node->getDoubleValue(
"xg");
66 double ye = body_node->getDoubleValue(
"ye");
67 double ze = body_node->getDoubleValue(
"ze");
68 double ra = atan2(ye, xs);
69 double dec = atan2(ze, sqrt(xs * xs + ye * ye));
71 tmp = ra - (SGD_2PI/24)*gst;
73 double signedPI = (tmp < 0.0) ? -SGD_PI : SGD_PI;
74 tmp = fmod(tmp+signedPI, SGD_2PI) - signedPI;
80static double body_angle(
const SGTime &t,
const SGVec3d& world_up,
bool sun_not_moon) {
81 const char *body = sun_not_moon ?
"sun" :
"moon";
82 SG_LOG( SG_EVENT, SG_DEBUG,
" Updating " << body <<
" position" );
83 SG_LOG( SG_EVENT, SG_DEBUG,
" Gst = " << t.getGst() );
87 SGVec3d bodypos = SGVec3d::fromGeoc(SGGeoc::fromRadM(lon, gc_lat,
90 SG_LOG( SG_EVENT, SG_DEBUG,
" t.cur_time = " << t.get_cur_time() );
91 SG_LOG( SG_EVENT, SG_DEBUG,
92 " " << body <<
" geocentric lat = " << gc_lat );
95 SGVec3d nup = normalize(world_up);
96 SGVec3d nbody = normalize(bodypos);
102 double body_angle = acos( dot( nup, nbody ) );
104 double signedPI = (
body_angle < 0.0) ? -SGD_PI : SGD_PI;
107 double body_angle_deg =
body_angle * SG_RADIANS_TO_DEGREES;
108 SG_LOG( SG_EVENT, SG_DEBUG, body <<
" angle relative to current location = "
111 return body_angle_deg;
125 double target_angle_deg,
129 SGVec3d world_up = SGVec3d::fromGeod(loc);
130 SGTime t = SGTime( loc, SGPath(), 0 );
132 double best_diff = 180.0;
133 double last_angle = -99999.0;
134 time_t best_time = cur_time;
140 t.update( loc, secs, 0 );
141 double angle_deg =
body_angle( t, world_up, sun_not_moon );
142 double diff = fabs( angle_deg - target_angle_deg );
143 if ( diff < best_diff ) {
144 if ( last_angle <= 180.0 && ascending
145 && ( last_angle > angle_deg ) ) {
150 }
else if ( last_angle <= 180.0 && !ascending
151 && ( last_angle < angle_deg ) ) {
159 last_angle = angle_deg;
162 return best_time - cur_time;
static const time_t day_secs
static const time_t step_secs
void fgBodyPositionGST(double gst, double &lon, double &lat, bool sun_not_moon)
given a particular time expressed in side real time at prime meridian (GST), compute position on the ...
static const time_t half_day_secs
time_t fgTimeSecondsUntilBodyAngle(time_t cur_time, const SGGeod &loc, double target_angle_deg, bool ascending, bool sun_not_moon)
Given the current unix time in seconds, calculate seconds to the specified body angle (relative to st...
static double body_angle(const SGTime &t, const SGVec3d &world_up, bool sun_not_moon)