Example #1
0
void
AATPoint::set_target(const fixed range, const fixed radial,
                     const TaskProjection &proj)
{
  fixed oldrange = fixed_zero;
  fixed oldradial = fixed_zero;
  get_target_range_radial(oldrange, oldradial);

  const FlatPoint fprev = proj.fproject(get_previous()->get_location_remaining());
  const FlatPoint floc = proj.fproject(get_location());
  const FlatLine flb (fprev,floc);
  const FlatLine fradius (floc,proj.fproject(get_location_min()));
  const fixed bearing = fixed_minus_one * flb.angle().value_degrees();
  const fixed radius = fradius.d();

  fixed swapquadrants = fixed_zero;
  if (positive(range) != positive(oldrange))
    swapquadrants = fixed(180);
  const FlatPoint ftarget1 (fabs(range) * radius *
        cos((bearing + radial + swapquadrants)
            / fixed(360) * fixed_two_pi),
      fabs(range) * radius *
        sin( fixed_minus_one * (bearing + radial + swapquadrants)
            / fixed(360) * fixed_two_pi));

  const FlatPoint ftarget2 = floc + ftarget1;
  const GeoPoint targetG = proj.funproject(ftarget2);

  set_target(targetG, true);
}
Example #2
0
void
AATPoint::SetTarget(const fixed range, const fixed radial,
                    const TaskProjection &proj)
{
  fixed oldrange = fixed_zero;
  fixed oldradial = fixed_zero;
  GetTargetRangeRadial(oldrange, oldradial);

  const FlatPoint fprev =
    proj.ProjectFloat(GetPrevious()->GetLocationRemaining());
  const FlatPoint floc = proj.ProjectFloat(GetLocation());
  const FlatLine flb (fprev,floc);
  const FlatLine fradius (floc,proj.ProjectFloat(GetLocationMin()));
  const fixed bearing = fixed_minus_one * flb.angle().Degrees();
  const fixed radius = fradius.d();

  fixed swapquadrants = fixed_zero;
  if (positive(range) != positive(oldrange))
    swapquadrants = fixed(180);
  const FlatPoint ftarget1 (fabs(range) * radius *
        cos((bearing + radial + swapquadrants)
            / fixed(360) * fixed_two_pi),
      fabs(range) * radius *
        sin( fixed_minus_one * (bearing + radial + swapquadrants)
            / fixed(360) * fixed_two_pi));

  const FlatPoint ftarget2 = floc + ftarget1;
  const GeoPoint targetG = proj.Unproject(ftarget2);

  SetTarget(targetG, true);
}
Example #3
0
bool
FlatLine::intersect_circle(const fixed r, const FlatPoint c,
                           FlatPoint &i1, FlatPoint &i2) const
{
  FlatLine that = *this;
  that.sub(c);
  if (that.intersect_czero(r, i1, i2)) {
    i1 = i1 + c;
    i2 = i2 + c;
    return true;
  }

  return false;
}
Example #4
0
/**
 * Check if the two wave lines match, and attempt to merge them.
 *
 * TODO: this is clumsy and unoptimised code; please improve!
 *
 * @return true if the lines have been merged into #a
 */
static bool
MergeLines(FlatLine &a, const FlatLine b)
{
  const double a_sq = a.GetSquaredDistance();
  const double b_sq = b.GetSquaredDistance();

  const double max_sq_distance =
    (std::max(a_sq, b_sq) + 2 * std::min(a_sq, b_sq)) / 250;

  const RatioAndDistance results[] = {
    CalcRatioAndDistance(a, b.a),
    CalcRatioAndDistance(a, b.b),
    CalcRatioAndDistance(b, a.a),
    CalcRatioAndDistance(b, a.b),
  };

  /* if two out of 4 line endpoints must be near the other line */
  unsigned n_distance_ok = 0;
  for (auto i : results)
    if (i.squared_distance <= max_sq_distance)
      ++n_distance_ok;

  if (n_distance_ok < 2)
    return false;

  /* the ratio of at least one point must be in range */
  unsigned n_ratio_ok = 0;
  for (auto i : results)
    if (IsRatioInRange(i.ratio))
      ++n_ratio_ok;

  if (n_ratio_ok == 0)
    return false;

  /* we can merge!  now check if we should extend the original (old)
     line because the new one exceeds it */

  if (results[0].ratio < 0)
    a.a = b.a;

  if (results[1].ratio > 1)
    a.b = b.b;

  return true;
}
Example #5
0
/**
 * Wrapper for FlatLine::Interpolate() which will clip the ratio to
 * [0..1] so the result stays within the [a..b] bounds.
 */
static constexpr FlatPoint
InterpolateClip(const FlatLine line, double ratio)
{
  return ratio <= 0
    ? line.a
    : (ratio >= 1
       ? line.b
       : line.Interpolate(ratio));
}
Example #6
0
gcc_pure
static RatioAndDistance
CalcRatioAndDistance(const FlatLine line, const FlatPoint point)
{
  RatioAndDistance result;
  result.ratio = line.ProjectedRatio(point);
  FlatPoint projected = InterpolateClip(line, result.ratio);
  result.squared_distance = (point - projected).MagnitudeSquared();
  return result;
}
Example #7
0
void
AATPoint::SetTarget(RangeAndRadial rar, const FlatProjection &proj)
{
  const auto fprev =
    proj.ProjectFloat(GetPrevious()->GetLocationRemaining());
  const auto floc = proj.ProjectFloat(GetLocation());
  const FlatLine flb (fprev,floc);
  const FlatLine fradius(floc,
                         proj.ProjectFloat(negative(rar.range)
                                           ? GetLocationMin()
                                           : GetLocationMax()));
  const auto radius = fradius.d() * fabs(rar.range);

  const auto angle = rar.radial - flb.angle();

  const FlatPoint ftarget1(radius * angle.cos(),
                           radius * -(angle).sin());

  const auto ftarget2 = floc + ftarget1;
  const auto targetG = proj.Unproject(ftarget2);

  SetTarget(targetG, true);
}