Esempio n. 1
0
gcc_pure
static Angle
CalcIntermediateAngle(const SeeYouTurnpointInformation &turnpoint_infos,
                      const GeoPoint &location,
                      const GeoPoint &start,
                      const GeoPoint &previous,
                      const GeoPoint &next)
{
    switch (turnpoint_infos.style) {
    case SeeYouTurnpointInformation::FIXED:
      return turnpoint_infos.angle12.Reciprocal();

    case SeeYouTurnpointInformation::SYMMETRICAL:
      break;

    case SeeYouTurnpointInformation::TO_NEXT_POINT:
      return next.Bearing(location);

    case SeeYouTurnpointInformation::TO_PREVIOUS_POINT:
      return previous.Bearing(location);

    case SeeYouTurnpointInformation::TO_START_POINT:
      return start.Bearing(location);
    }

    /* SYMMETRICAL is the fallback when the file contained an
       invalid/unknown style */
    const Angle ap = previous.Bearing(location);
    const Angle an = next.Bearing(location);
    return ap.HalfAngle(an).Reciprocal();
}
bool
FAITrianglePointValidator::IsFAIAngle(const GeoPoint &p0, const GeoPoint &p1,
                                      const GeoPoint &p2, bool right)
{
  const Angle a01 = p0.Bearing(p1);
  const Angle a21 = p2.Bearing(p1);
  const Angle diff = (a01 - a21).AsDelta();

  if (right)
    return (diff > min_fai_angle) && (diff < max_fai_angle);
  else
    return diff < -min_fai_angle && diff > -max_fai_angle;
}
Esempio n. 3
0
  /**
   * Perform fast check to exclude point as from further consideration
   * based on min/max possible values for any FAI triangle
   * @param p0 point 1 of angle
   * @param p1 point 2 of angle
   * @param p2 point 3 of angle
   * @param right.  = 1 if angle is for right triangle, -1 if left triangle.
   * @returns False if angle from three points is out of possible range for
   * an FAI triangle.
   */
  bool
  IsFAIAngle(const GeoPoint &p0, const GeoPoint &p1, const GeoPoint &p2,
             const fixed right)
  {
    const Angle a01 = p0.Bearing(p1);
    const Angle a21 = p2.Bearing(p1);
    const fixed diff = (a01 - a21).AsDelta().Degrees();

    if (positive(right))
      return (diff > min_fai_angle) && (diff < max_fai_angle);
    else
      return (diff < fixed(-1) * min_fai_angle) && (diff > fixed(-1)
              * max_fai_angle);
  }
Esempio n. 4
0
bool
AirspaceFilterData::Match(const GeoPoint &location,
                          const FlatProjection &projection,
                          const AbstractAirspace &as) const
{
  if (cls != AirspaceClass::AIRSPACECLASSCOUNT && as.GetType() != cls)
    return false;

  if (name_prefix != nullptr && !as.MatchNamePrefix(name_prefix))
    return false;

  if (!direction.IsNegative()) {
    const auto closest = as.ClosestPoint(location, projection);
    const auto bearing = location.Bearing(closest);
    auto direction_error = (bearing - direction).AsDelta().AbsoluteDegrees();
    if (direction_error > fixed(18))
      return false;
  }

  if (!negative(distance)) {
    const auto closest = as.ClosestPoint(location, projection);
    const auto distance = location.Distance(closest);
    if (distance > distance)
      return false;
  }

  return true;
}
Esempio n. 5
0
void
DeviceBlackboard::SetSimulatorLocation(const GeoPoint &location)
{
  ScopeLock protect(mutex);
  NMEAInfo &basic = simulator_data;

  simulator.Touch(basic);
  basic.track = location.Bearing(basic.location).Reciprocal();
  basic.location = location;

  ScheduleMerge();
}
Esempio n. 6
0
void
AATPoint::GetTargetRangeRadial(fixed &range, fixed &radial) const
{
  const fixed oldrange = range;

  const GeoPoint fprev = GetPrevious()->GetLocationRemaining();
  const GeoPoint floc = GetLocation();
  const Angle radialraw = (floc.Bearing(GetTargetLocation()) -
      fprev.Bearing(floc)).AsBearing();

  const fixed d = floc.Distance(GetTargetLocation());
  const fixed radius = floc.Distance(GetLocationMin());
  const fixed rangeraw = min(fixed_one, d / radius);

  radial = radialraw.AsDelta().Degrees();
  const fixed rangesign = (fabs(radial) > fixed(90)) ?
      fixed_minus_one : fixed_one;
  range = rangeraw * rangesign;

  if ((oldrange == fixed_zero) && (range == fixed_zero))
    radial = fixed_zero;
}
Esempio n. 7
0
RangeAndRadial
AATPoint::GetTargetRangeRadial(fixed oldrange) const
{
  const GeoPoint fprev = GetPrevious()->GetLocationRemaining();
  const GeoPoint floc = GetLocation();
  const Angle radialraw = (floc.Bearing(GetTargetLocation()) -
      fprev.Bearing(floc)).AsBearing();
  Angle radial = radialraw.AsDelta();

  fixed d = floc.Distance(GetTargetLocation());
  if (radial < -Angle::QuarterCircle() || radial > Angle::QuarterCircle())
    d = -d;

  const fixed radius = negative(d)
    ? floc.Distance(GetLocationMin())
    : floc.Distance(GetLocationMax());
  const fixed range = Clamp(d / radius, fixed(-1), fixed(1));

  if (oldrange == fixed(0) && range == fixed(0))
    radial = Angle::Zero();

  return RangeAndRadial{ range, radial };
}
Esempio n. 8
0
inline GeoVector
TaskLeg::GetTravelledVector(const GeoPoint &ref) const
{
  switch (destination.GetActiveState()) {
  case OrderedTaskPoint::BEFORE_ACTIVE:
    if (!GetOrigin())
      return GeoVector::Zero();

    // this leg totally included
    return memo_travelled.calc(GetOrigin()->GetLocationTravelled(),
                               destination.GetLocationTravelled());

  case OrderedTaskPoint::CURRENT_ACTIVE:
    // this leg partially included
    if (!GetOrigin())
      return GeoVector(0,
                       ref.IsValid()
                       ? ref.Bearing(destination.GetLocationRemaining())
                       : Angle::Zero());

    if (destination.HasEntered())
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(),
                                 destination.GetLocationTravelled());
    else if (!ref.IsValid())
      return GeoVector::Zero();
    else
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(), ref);

  case OrderedTaskPoint::AFTER_ACTIVE:
    if (!GetOrigin())
      return GeoVector::Zero();

    // this leg may be partially included
    if (GetOrigin()->HasEntered())
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(),
                                 ref.IsValid()
                                 ? ref
                                 : destination.GetLocationTravelled());

    return GeoVector::Zero();
  }

  gcc_unreachable();
  assert(false);
  return GeoVector::Invalid();
}
Esempio n. 9
0
/**
 * Convert a #LeastSquares to a #WaveInfo.  Returns
 * WaveInfo::Undefined() if there is no valid result in the
 * #LeastSquares instance.
 */
gcc_pure
static WaveInfo
GetWaveInfo(const LeastSquares &ls, const FlatProjection &projection,
            double time)
{
  if (!ls.HasResult())
    return WaveInfo::Undefined();

  const FlatPoint flat_location(ls.GetMiddleX(), ls.GetAverageY());
  const GeoPoint location(projection.Unproject(flat_location));

  const GeoPoint a(projection.Unproject(FlatPoint(ls.GetMinX(),
                                                  ls.GetYAtMinX())));
  const GeoPoint b(projection.Unproject(FlatPoint(ls.GetMaxX(),
                                                  ls.GetYAtMaxX())));

  Angle bearing = a.Bearing(b);
  Angle normal = (bearing + Angle::QuarterCircle()).AsBearing();

  return {location, a, b, normal, time};
}
Esempio n. 10
0
  void
  AppendArc(const GeoPoint start, const GeoPoint end)
  {

    // Determine start bearing and radius
    const GeoVector v = center.DistanceBearing(start);
    Angle start_bearing = v.bearing;
    const fixed radius = v.distance;

    // 5 or -5, depending on direction
    const auto _step = ArcStepWidth(radius);
    const Angle step = Angle::Degrees(rotation * _step);
    const fixed threshold = _step * fixed(1.5);

    // Determine end bearing
    Angle end_bearing = center.Bearing(end);

    if (rotation > 0) {
      while (end_bearing < start_bearing)
        end_bearing += Angle::FullCircle();
    } else if (rotation < 0) {
      while (end_bearing > start_bearing)
        end_bearing -= Angle::FullCircle();
    }

    // Add first polygon point
    points.push_back(start);

    // Add intermediate polygon points
    while ((end_bearing - start_bearing).AbsoluteDegrees() > threshold) {
      start_bearing += step;
      points.push_back(FindLatitudeLongitude(center, start_bearing, radius));
    }

    // Add last polygon point
    points.push_back(end);
  }
Esempio n. 11
0
GeoVector
TaskLeg::GetTravelledVector(const GeoPoint &ref) const
{
  switch (destination.GetActiveState()) {
  case OrderedTaskPoint::BEFORE_ACTIVE:
    if (!GetOrigin())
      return GeoVector(fixed(0));

    // this leg totally included
    return memo_travelled.calc(GetOrigin()->GetLocationTravelled(),
                               destination.GetLocationTravelled());

  case OrderedTaskPoint::CURRENT_ACTIVE:
    // this leg partially included
    if (!GetOrigin())
      return GeoVector(fixed(0), 
                       ref.Bearing(destination.GetLocationRemaining()));

    if (destination.HasEntered())
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(),
                                 destination.GetLocationTravelled());
    else
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(), ref);

  case OrderedTaskPoint::AFTER_ACTIVE:
    if (!GetOrigin())
      return GeoVector(fixed(0));

    // this leg may be partially included
    if (GetOrigin()->HasEntered())
      return memo_travelled.calc(GetOrigin()->GetLocationTravelled(), ref);

  default:
    return GeoVector(fixed(0));
  };
}