diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 3e1d9e7ce..ff97eb897 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -501,30 +501,57 @@ do_timeofday (const SGPropertyNode * arg) // cout << "orig_warp = " << orig_warp << endl; int warp = 0; - if ( offset_type == "noon" ) { - warp = fgTimeSecondsUntilNoon( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); - } else if ( offset_type == "midnight" ) { - warp = fgTimeSecondsUntilMidnight( cur_time, + if ( offset_type == "real" ) { + warp = 0; + } else if ( offset_type == "dawn" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); - } else if ( offset_type == "dawn" ) { - warp = fgTimeSecondsUntilDawn( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); + * SGD_DEGREES_TO_RADIANS, + 90.0, true ); + } else if ( offset_type == "morning" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 75.0, true ); + } else if ( offset_type == "noon" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 0.0, true ); + } else if ( offset_type == "afternoon" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 60.0, false ); } else if ( offset_type == "dusk" ) { - warp = fgTimeSecondsUntilDusk( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 90.0, false ); + } else if ( offset_type == "evening" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 100.0, false ); + } else if ( offset_type == "midnight" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 180.0, false ); } // cout << "warp = " << warp << endl; globals->set_warp( orig_warp + warp ); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 43e620e2d..fb94e6179 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1286,32 +1286,60 @@ void fgInitTimeOffset() { // Okay, we now have several possible scenarios int offset = fgGetInt("/sim/startup/time-offset"); - int warp = 0; const string &offset_type = fgGetString("/sim/startup/time-offset-type"); - if ( offset_type == "noon" ) { - warp = fgTimeSecondsUntilNoon( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); - } else if ( offset_type == "midnight" ) { - warp = fgTimeSecondsUntilMidnight( cur_time, + + int warp = 0; + if ( offset_type == "real" ) { + warp = 0; + } else if ( offset_type == "dawn" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); - } else if ( offset_type == "dawn" ) { - warp = fgTimeSecondsUntilDawn( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); + * SGD_DEGREES_TO_RADIANS, + 90.0, true ); + } else if ( offset_type == "morning" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 75.0, true ); + } else if ( offset_type == "noon" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 0.0, true ); + } else if ( offset_type == "afternoon" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 60.0, false ); } else if ( offset_type == "dusk" ) { - warp = fgTimeSecondsUntilDusk( cur_time, - longitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS, - latitude->getDoubleValue() - * SGD_DEGREES_TO_RADIANS ); + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 90.0, false ); + } else if ( offset_type == "evening" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 100.0, false ); + } else if ( offset_type == "midnight" ) { + warp = fgTimeSecondsUntilSunAngle( cur_time, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + 180.0, false ); } else if ( offset_type == "system-offset" ) { warp = offset; } else if ( offset_type == "gmt-offset" ) { diff --git a/src/Time/sunsolver.cxx b/src/Time/sunsolver.cxx index c4e48c434..b0d0d5c4f 100644 --- a/src/Time/sunsolver.cxx +++ b/src/Time/sunsolver.cxx @@ -81,47 +81,18 @@ static double sun_angle( const SGTime &t, sgVec3 world_up, /** - * Given the current unix time in seconds, calculate seconds to noon + * Given the current unix time in seconds, calculate seconds to the + * specified sun angle (relative to straight up.) Also specify if we + * want the angle while the sun is ascending or descending. 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 + * when the sun angle is 90 and ascending. */ -time_t fgTimeSecondsUntilNoon( time_t cur_time, - double lon_rad, - double lat_rad ) -{ - // cout << "location = " << lon_rad * SG_RADIANS_TO_DEGREES << ", " - // << lat_rad * SG_RADIANS_TO_DEGREES << endl; - Point3D geod( lon_rad, lat_rad, 0 ); - Point3D tmp = sgGeodToCart( geod ); - sgVec3 world_up; - sgSetVec3( world_up, tmp.x(), tmp.y(), tmp.z() ); - SGTime t = SGTime( lon_rad, lat_rad, "", 0 ); - - double best_angle = 180.0; - time_t best_time = cur_time; - - for ( time_t secs = cur_time - half_day_secs; - secs < cur_time + half_day_secs; - secs += step_secs ) - { - t.update( lon_rad, lat_rad, secs, 0 ); - double angle = sun_angle( t, world_up, lon_rad, lat_rad ); - if ( angle < best_angle ) { - // cout << "best angle = " << angle << " offset = " - // << secs - cur_time << endl; - best_angle = angle; - best_time = secs; - } - } - - return best_time - cur_time; -} - - -/** - * Given the current unix time in seconds, calculate seconds to midnight - */ -time_t fgTimeSecondsUntilMidnight( time_t cur_time, +time_t fgTimeSecondsUntilSunAngle( time_t cur_time, double lon_rad, - double lat_rad ) + double lat_rad, + double target_angle_deg, + bool ascending ) { // cout << "location = " << lon_rad * SG_RADIANS_TO_DEGREES << ", " // << lat_rad * SG_RADIANS_TO_DEGREES << endl; @@ -131,43 +102,7 @@ time_t fgTimeSecondsUntilMidnight( time_t cur_time, sgSetVec3( world_up, tmp.x(), tmp.y(), tmp.z() ); SGTime t = SGTime( lon_rad, lat_rad, "", 0 ); - double best_angle = 0.0; - time_t best_time = cur_time; - - for ( time_t secs = cur_time - half_day_secs; - secs < cur_time + half_day_secs; - secs += step_secs ) - { - t.update( lon_rad, lat_rad, secs, 0 ); - double angle = sun_angle( t, world_up, lon_rad, lat_rad ); - if ( angle > best_angle ) { - // cout << "best angle = " << angle << " offset = " - // << secs - cur_time << endl; - best_angle = angle; - best_time = secs; - } - } - - return best_time - cur_time; -} - - -/** - * Given the current unix time in seconds, calculate seconds to dusk - */ -time_t fgTimeSecondsUntilDusk( time_t cur_time, - double lon_rad, - double lat_rad ) -{ - // cout << "location = " << lon_rad * SG_RADIANS_TO_DEGREES << ", " - // << lat_rad * SG_RADIANS_TO_DEGREES << endl; - Point3D geod( lon_rad, lat_rad, 0 ); - Point3D tmp = sgGeodToCart( geod ); - sgVec3 world_up; - sgSetVec3( world_up, tmp.x(), tmp.y(), tmp.z() ); - SGTime t = SGTime( lon_rad, lat_rad, "", 0 ); - - double best_diff = 90.0; + double best_diff = 180.0; double last_angle = -99999.0; time_t best_time = cur_time; @@ -176,10 +111,17 @@ time_t fgTimeSecondsUntilDusk( time_t cur_time, secs += step_secs ) { t.update( lon_rad, lat_rad, secs, 0 ); - double angle = sun_angle( t, world_up, lon_rad, lat_rad ); - double diff = fabs( angle - 90.0 ); + double angle_deg = sun_angle( t, world_up, lon_rad, lat_rad ); + double diff = fabs( angle_deg - target_angle_deg ); if ( diff < best_diff ) { - if ( last_angle <= 180.0 && ( last_angle < angle ) ) { + if ( last_angle <= 180.0 && ascending + && ( last_angle > angle_deg ) ) { + // cout << "best angle = " << angle << " offset = " + // << secs - cur_time << endl; + best_diff = diff; + best_time = secs; + } else if ( last_angle <= 180.0 && !ascending + && ( last_angle < angle_deg ) ) { // cout << "best angle = " << angle << " offset = " // << secs - cur_time << endl; best_diff = diff; @@ -187,49 +129,7 @@ time_t fgTimeSecondsUntilDusk( time_t cur_time, } } - last_angle = angle; - } - - return best_time - cur_time; -} - - -/** - * Given the current unix time in seconds, calculate seconds to dawn - */ -time_t fgTimeSecondsUntilDawn( time_t cur_time, - double lon_rad, - double lat_rad ) -{ - // cout << "location = " << lon_rad * SG_RADIANS_TO_DEGREES << ", " - // << lat_rad * SG_RADIANS_TO_DEGREES << endl; - Point3D geod( lon_rad, lat_rad, 0 ); - Point3D tmp = sgGeodToCart( geod ); - sgVec3 world_up; - sgSetVec3( world_up, tmp.x(), tmp.y(), tmp.z() ); - SGTime t = SGTime( lon_rad, lat_rad, "", 0 ); - - double best_diff = 90.0; - double last_angle = -99999.0; - time_t best_time = cur_time; - - for ( time_t secs = cur_time - half_day_secs; - secs < cur_time + half_day_secs; - secs += step_secs ) - { - t.update( lon_rad, lat_rad, secs, 0 ); - double angle = sun_angle( t, world_up, lon_rad, lat_rad ); - double diff = fabs( angle - 90.0 ); - if ( diff < best_diff ) { - if ( last_angle <= 180.0 && ( last_angle > angle ) ) { - // cout << "best angle = " << angle << " offset = " - // << secs - cur_time << endl; - best_diff = diff; - best_time = secs; - } - } - - last_angle = angle; + last_angle = angle_deg; } return best_time - cur_time; diff --git a/src/Time/sunsolver.hxx b/src/Time/sunsolver.hxx index 6ba4c4208..8d8b4b8fa 100644 --- a/src/Time/sunsolver.hxx +++ b/src/Time/sunsolver.hxx @@ -41,37 +41,17 @@ #endif /** - * Given the current unix time in seconds, calculate seconds to - * highest sun angle. + * Given the current unix time in seconds, calculate seconds to the + * specified sun angle (relative to straight up.) Also specify if we + * want the angle while the sun is ascending or descending. 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 + * when the sun angle is 90 and ascending. */ -time_t fgTimeSecondsUntilNoon( time_t cur_time, - double lon_rad, - double lat_rad ); - - -/** - * Given the current unix time in seconds, calculate seconds to lowest - * sun angle. - */ -time_t fgTimeSecondsUntilMidnight( time_t cur_time, +time_t fgTimeSecondsUntilSunAngle( time_t cur_time, double lon_rad, - double lat_rad ); - -/** - * Given the current unix time in seconds, calculate seconds to dusk - */ -time_t fgTimeSecondsUntilDusk( time_t cur_time, - double lon_rad, - double lat_rad ); - - -/** - * Given the current unix time in seconds, calculate seconds to dawn - */ -time_t fgTimeSecondsUntilDawn( time_t cur_time, - double lon_rad, - double lat_rad ); - - + double lat_rad, + double target_angle_deg, + bool ascending ); #endif /* _SUNSOLVER_HXX */