Exemple #1
0
fixed
ProjectedDistance(GeoPoint loc1, GeoPoint loc2, GeoPoint loc3)
{
  Angle dist_AD; Angle crs_AD;
  DistanceBearingS(loc1, loc3, &dist_AD, &crs_AD);
  if (!positive(dist_AD.value_native()))
    /* workaround: new sine implementation may return small non-zero
       values for sin(0) */
    return fixed_zero;

  Angle dist_AB; Angle crs_AB;
  DistanceBearingS(loc1, loc2, &dist_AB, &crs_AB);
  if (!positive(dist_AB.value_native()))
    /* workaround: new sine implementation may return small non-zero
       values for sin(0) */
    return fixed_zero;

  // The "along track distance", ATD, the distance from A along the
  // course towards B to the point abeam D

  const fixed sindist_AD = dist_AD.sin();
  const fixed XTD(earth_asin(sindist_AD * (crs_AD - crs_AB).sin())); // cross track distance

  fixed sinXTD, cosXTD;
  sin_cos(XTD, &sinXTD, &cosXTD);

  // along track distance
  const fixed ATD(earth_asin(sqrt(sindist_AD * sindist_AD - sinXTD * sinXTD) / cosXTD));

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return ATD * fixed_earth_r;
}
Exemple #2
0
fixed
CrossTrackError(GeoPoint loc1, GeoPoint loc2, GeoPoint loc3, GeoPoint *loc4)
{
  Angle dist_AD; Angle crs_AD;
  DistanceBearingS(loc1, loc3, &dist_AD, &crs_AD);

  Angle dist_AB; Angle crs_AB;
  DistanceBearingS(loc1, loc2, &dist_AB, &crs_AB);

  //  The "along track distance", ATD, the distance from A along the
  //  course towards B to the point abeam D

  const fixed sindist_AD = dist_AD.sin();
  // cross track distance
  const fixed XTD(earth_asin(sindist_AD * (crs_AD - crs_AB).sin()));

  if (loc4) {
    fixed sinXTD, cosXTD;
    sin_cos(XTD, &sinXTD, &cosXTD);

    // along track distance
    const fixed ATD(earth_asin(sqrt(sindist_AD * sindist_AD - sinXTD * sinXTD)
                         / cosXTD));

    *loc4 = IntermediatePoint(loc1, loc2, ATD, dist_AB.value_radians());
  }

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  // units
  return XTD * fixed_earth_r;
}
Exemple #3
0
fixed
CrossTrackError(const GeoPoint loc1, const GeoPoint loc2,
                const GeoPoint loc3, GeoPoint *loc4)
{
  Angle dist_AD, crs_AD;
  DistanceBearingS(loc1, loc3, &dist_AD, &crs_AD);

  Angle dist_AB, crs_AB;
  DistanceBearingS(loc1, loc2, &dist_AB, &crs_AB);

  //  The "along track distance", ATD, the distance from A along the
  //  course towards B to the point abeam D

  const fixed sindist_AD = dist_AD.sin();

  // cross track distance
  const fixed cross_track_distance =
    earth_asin(sindist_AD * (crs_AD - crs_AB).sin());

  if (loc4) {
    const auto sc = sin_cos(cross_track_distance);
    const fixed sinXTD = sc.first, cosXTD = sc.second;

    const fixed along_track_distance =
      earth_asin(sqrt(sindist_AD * sindist_AD - sinXTD * sinXTD) / cosXTD);

    *loc4 = IntermediatePoint(loc1, loc2, along_track_distance, dist_AB.Radians());
  }

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return cross_track_distance * fixed_earth_r;
}
Exemple #4
0
/**
 * Calculates the location (loc_out) you would have, after being at
 * a certain start location (loc) with a certain Bearing and going straight
 * forward for a certain Distance.
 * @param loc Current location
 * @param Bearing Current bearing
 * @param Distance Distance to predict
 * @param loc_out Future location
 */
GeoPoint
FindLatitudeLongitude(GeoPoint loc, Angle Bearing, 
                      fixed Distance)
{
  assert(!negative(Distance));
  if (!positive(Distance))
    return loc;

  GeoPoint loc_out;
  Distance *= fixed_inv_earth_r;

  fixed sinDistance, cosDistance;
  sin_cos(Distance, &sinDistance, &cosDistance);

  fixed sinBearing, cosBearing;
  Bearing.sin_cos(sinBearing, cosBearing);

  fixed sinLatitude, cosLatitude;
  loc.Latitude.sin_cos(sinLatitude, cosLatitude);

  loc_out.Latitude = Angle::radians(earth_asin(sinLatitude * cosDistance + cosLatitude
                                         * sinDistance * cosBearing));

  fixed result;

  if (cosLatitude == fixed_zero)
    result = loc.Longitude.value_radians();
  else {
    result = loc.Longitude.value_radians() + 
      earth_asin(sinBearing * sinDistance / cosLatitude);
  }

  loc_out.Longitude = Angle::radians(result);
  loc_out.normalize(); // ensure longitude is within -180:180

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return loc_out;
}
Exemple #5
0
fixed
ProjectedDistance(const GeoPoint loc1, const GeoPoint loc2, const GeoPoint loc3)
{
  Angle dist_AD, crs_AD;
  DistanceBearingS(loc1, loc3, &dist_AD, &crs_AD);
  if (!positive(dist_AD.Native()))
    /* workaround: new sine implementation may return small non-zero
       values for sin(0) */
    return fixed_zero;

  Angle dist_AB, crs_AB;
  DistanceBearingS(loc1, loc2, &dist_AB, &crs_AB);
  if (!positive(dist_AB.Native()))
    /* workaround: new sine implementation may return small non-zero
       values for sin(0) */
    return fixed_zero;

  // The "along track distance", along_track_distance, the distance from A along the
  // course towards B to the point abeam D

  const fixed sindist_AD = dist_AD.sin();
  const fixed cross_track_distance =
      earth_asin(sindist_AD * (crs_AD - crs_AB).sin());

  const auto sc = sin_cos(cross_track_distance);
  const fixed sinXTD = sc.first, cosXTD = sc.second;

  // along track distance
  const fixed along_track_distance =
    earth_asin(sqrt(sindist_AD * sindist_AD - sinXTD * sinXTD) / cosXTD);

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return along_track_distance * fixed_earth_r;
}
Exemple #6
0
static inline
fixed earth_distance_function(const fixed a) {
  if (!positive(a))
    return fixed_zero;

#ifdef FIXED_MATH
  // static const fixed fixed_shrink(fixed_two/(1<<(EXPAND_BITS*2)));
  // acos(1-x) = 2*asin(sqrt(x/2))
  // acos(1-2*x) = 2*asin(sqrt(x))
  //    = 2*atan2(sqrt(x), sqrt(fixed_one-x));
  return fixed_two*earth_asin(sqrt(a)/(1<<fixed::accurate_cordic_shift));
#else
  return acos(fixed_one-fixed_two*a);
#endif
}
Exemple #7
0
GeoPoint
FindLatitudeLongitude(const GeoPoint loc, const Angle bearing,
                      fixed distance)
{
  assert(!negative(distance));
  if (!positive(distance))
    return loc;

  GeoPoint loc_out;
  distance *= fixed_inv_earth_r;

  const auto scd = sin_cos(distance);
  const fixed sin_distance = scd.first, cos_distance = scd.second;

  const auto scb = bearing.SinCos();
  const fixed sin_bearing = scb.first, cos_bearing = scb.second;

  const auto scl = loc.latitude.SinCos();
  const fixed sin_latitude = scl.first, cos_latitude = scl.second;

  loc_out.latitude = Angle::Radians(earth_asin(
      sin_latitude * cos_distance + cos_latitude * sin_distance * cos_bearing));

  fixed result = loc.longitude.Radians();
  if (cos_latitude != fixed_zero)
    result += earth_asin(sin_bearing * sin_distance / cos_latitude);

  loc_out.longitude = Angle::Radians(result);
  loc_out.Normalize(); // ensure longitude is within -180:180

#ifdef INSTRUMENT_TASK
  count_distbearing++;
#endif

  return loc_out;
}