/** * Calculates all sun-related important times * depending on time of year and location * @param Location Location to be used in calculation * @param Basic NMEA_INFO for current date * @param Calculated DERIVED_INFO (not yet used) * @param TimeZone The timezone * @return Sunset time */ void SunEphemeris::CalcSunTimes(const GeoPoint &Location, const BrokenDateTime &date_time, const fixed TimeZone) { fixed DaysToJ2000 = FNday(date_time); Angle L = GetMeanSunLongitude(DaysToJ2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle Lambda = GetEclipticLongitude(DaysToJ2000, L); // Obliquity of the ecliptic Angle Obliquity = Angle::degrees(fixed(23.439) - fixed(.0000004) * DaysToJ2000); // Find the RA and DEC of the Sun Angle Alpha = Angle::radians(atan2(Obliquity.cos() * Lambda.sin(), Lambda.cos())); Angle Delta = Angle::radians(asin(Obliquity.sin() * Lambda.sin())); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed LL = (L - Alpha).value_radians(); if (L.value_radians() < fixed_pi) LL += fixed_two_pi; fixed equation = fixed(1440) * (fixed_one - LL / fixed_two_pi); Angle HourAngle = GetHourAngle(Location.Latitude, Delta); Angle HourAngleTwilight = GetHourAngleTwilight(Location.Latitude, Delta); // length of twilight in hours fixed TwilightHours = (HourAngleTwilight - HourAngle).value_hours(); // Conversion of angle to hours and minutes DayLength = HourAngle.value_hours() * fixed_two; if (DayLength < fixed(0.0001)) // arctic winter DayLength = fixed_zero; TimeOfSunRise = fixed(12) - HourAngle.value_hours() + TimeZone - Location.Longitude.value_degrees() / 15 + equation / 60; if (TimeOfSunRise > fixed(24)) TimeOfSunRise -= fixed(24); TimeOfSunSet = TimeOfSunRise + DayLength; TimeOfNoon = TimeOfSunRise + HourAngle.value_hours(); // morning twilight begin MorningTwilight = TimeOfSunRise - TwilightHours; // evening twilight end EveningTwilight = TimeOfSunSet + TwilightHours; }
/** * Calculates the sun's azimuth at a given location and time * @param Location azimuth at what location * @param time azimuth at what time * @param dec precalculated declination angle * @return sun's azimuth * @see http://www.providence.edu/mcs/rbg/java/sungraph.htm */ static Angle CalculateAzimuth(const GeoPoint &Location, const BrokenTime &time, const fixed time_zone, const Angle dec) { assert(time.Plausible()); fixed T = fixed(time.GetSecondOfDay()) / 3600 - fixed(12) + time_zone; Angle t = Angle::Degrees(15) * T; return -Angle::FromXY(Location.latitude.cos() * dec.sin() - Location.latitude.sin() * dec.cos() * t.cos(), dec.cos() * t.sin()); }
void Frame2d::set_angle( const Angle & a ) { n_x = a.cos() * scale; n_y = a.sin() * scale; //f1.n_y= sqrt(1-f1.n_x*f1.n_x); }
Angle SunEphemeris::GetEclipticLongitude(fixed d, Angle L) { // mean anomaly of the Sun Angle g = Angle::Degrees(fixed(357.528) + fixed(.9856003) * d).AsBearing(); // Ecliptic longitude of the Sun return (Angle::Degrees(1.915) * g.sin() + L + Angle::Degrees(.02) * (g * fixed(2)).sin()).AsBearing(); }
gcc_pure static GeoPoint IntermediatePoint(const GeoPoint &loc1, const GeoPoint &loc2, Angle dthis, Angle dtotal) { assert(loc1.IsValid()); assert(loc2.IsValid()); if (loc1.longitude == loc2.longitude && loc1.latitude == loc2.latitude) return loc1; if (!positive(dtotal.Native())) return loc1; assert(dthis <= dtotal && !negative(dthis.Native())); const fixed A = (dtotal - dthis).sin(); const fixed B = dthis.sin(); const auto sc1 = loc1.latitude.SinCos(); const fixed sin_loc1_lat = sc1.first, cos_loc1_lat = sc1.second; const auto sc2 = loc2.latitude.SinCos(); const fixed sin_loc2_lat = sc2.first, cos_loc2_lat = sc2.second; const auto sc3 = loc1.longitude.SinCos(); const fixed sin_loc1_lon = sc3.first, cos_loc1_lon = sc3.second; const auto sc4 = loc2.longitude.SinCos(); const fixed sin_loc2_lon = sc4.first, cos_loc2_lon = sc4.second; const fixed a_cos_loc1_lat = SmallMult(A, cos_loc1_lat); const fixed b_cos_loc2_lat = SmallMult(B, cos_loc2_lat); const fixed x = SmallMult(a_cos_loc1_lat, cos_loc1_lon) + SmallMult(b_cos_loc2_lat, cos_loc2_lon); const fixed y = SmallMult(a_cos_loc1_lat, sin_loc1_lon) + SmallMult(b_cos_loc2_lat, sin_loc2_lon); const fixed z = SmallMult(A, sin_loc1_lat) + SmallMult(B, sin_loc2_lat); GeoPoint loc3; loc3.latitude = Angle::FromXY(TinyHypot(x, y), z); loc3.longitude = Angle::FromXY(x, y); loc3.Normalize(); // ensure longitude is within -180:180 #ifdef INSTRUMENT_TASK count_distbearing++; #endif return loc3; }
Angle SunEphemeris::CalcAzimuth(const GeoPoint &location, const BrokenDateTime &date_time, const fixed time_zone) { assert(date_time.Plausible()); fixed days_to_j2000 = FNday(date_time); Angle l = GetMeanSunLongitude(days_to_j2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle lambda = GetEclipticLongitude(days_to_j2000, l); // Obliquity of the ecliptic Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000); // Find the DEC of the Sun Angle delta = Angle::asin(obliquity.sin() * lambda.sin()); return CalculateAzimuth(location, date_time, time_zone, delta); }
void CalculateThetaWEst() { int i; for (i = 0; i < NUM_V_POINTS; i++) { fixed Vwest = ItoV(i); theta_west_ok[i] = EstimateW0(Vwest, i); } cos_theta_gps = theta_gps.cos(); sin_theta_gps = theta_gps.sin(); V_gps_x = iround(100 * V_gps * cos_theta_gps); V_gps_y = iround(100 * V_gps * sin_theta_gps); V_tas_l = iround(100 * V_tas); }
bool UpdateSearch_Inner(fixed V_west, Angle theta_best) { // given wind speed and direction, find TAS error int V_west_x = iround(100 * V_west * theta_best.cos()); int V_west_y = iround(100 * V_west * theta_best.sin()); int verr = VError(V_west_x, V_west_y); // search for minimum error // (this is not monotonous) if (verr >= error_best) return false; error_best = verr; V_west_best = V_west; theta_west_best = theta_best; return true; }
SunEphemeris::Result SunEphemeris::CalcSunTimes(const GeoPoint &location, const BrokenDateTime &date_time, const fixed time_zone) { Result result; assert(date_time.Plausible()); fixed days_to_j2000 = FNday(date_time); Angle l = GetMeanSunLongitude(days_to_j2000); // Use GetEclipticLongitude to find the ecliptic longitude of the Sun Angle lambda = GetEclipticLongitude(days_to_j2000, l); // Obliquity of the ecliptic Angle obliquity = Angle::Degrees(fixed(23.439) - fixed(.0000004) * days_to_j2000); // Find the RA and DEC of the Sun Angle alpha = Angle::FromXY(lambda.cos(), obliquity.cos() * lambda.sin()); Angle delta = Angle::asin(obliquity.sin() * lambda.sin()); // Find the Equation of Time in minutes // Correction suggested by David Smith fixed ll = (l - alpha).Radians(); if (l.Radians() < fixed_pi) ll += fixed_two_pi; fixed equation = fixed(1440) * (fixed(1) - ll / fixed_two_pi); Angle hour_angle = GetHourAngle(location.latitude, delta); Angle hour_angle_twilight = GetHourAngleTwilight(location.latitude, delta); result.azimuth = CalculateAzimuth(location, date_time, time_zone, delta); // length of twilight in hours fixed twilight_hours = (hour_angle_twilight - hour_angle).Hours(); // Conversion of angle to hours and minutes result.day_length = Double(hour_angle.Hours()); if (result.day_length < fixed(0.0001)) // arctic winter result.day_length = fixed(0); result.time_of_sunrise = fixed(12) - hour_angle.Hours() + time_zone - location.longitude.Degrees() / 15 + equation / 60; if (result.time_of_sunrise > fixed(24)) result.time_of_sunrise -= fixed(24); result.time_of_sunset = result.time_of_sunrise + result.day_length; result.time_of_noon = result.time_of_sunrise + hour_angle.Hours(); // morning twilight begin result.morning_twilight = result.time_of_sunrise - twilight_hours; // evening twilight end result.evening_twilight = result.time_of_sunset + twilight_hours; return result; }