Пример #1
0
/**
 * 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;
}
Пример #2
0
/**
 * 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());
}
Пример #3
0
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);
}
Пример #4
0
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();
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
  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);
  }
Пример #8
0
  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;
  }
Пример #9
0
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;
}