示例#1
0
AirspaceIntersectionVector
AirspaceCircle::Intersects(const GeoPoint &start, const GeoPoint &end,
                           const TaskProjection &projection) const
{
  const fixed f_radius = projection.fproject_range(m_center, m_radius);
  const FlatPoint f_center = projection.fproject(m_center);
  const FlatPoint f_start = projection.fproject(start);
  const FlatPoint f_end = projection.fproject(end);
  const FlatLine line(f_start, f_end);

  FlatPoint f_p1, f_p2;
  if (!line.intersect_circle(f_radius, f_center, f_p1, f_p2))
    return AirspaceIntersectionVector();

  const fixed mag = line.dsq();
  if (!positive(mag))
    return AirspaceIntersectionVector();

  const fixed inv_mag = fixed_one / mag;
  const fixed t1 = FlatLine(f_start, f_p1).dot(line);
  const fixed t2 = (f_p1 == f_p2) ?
    -fixed_one : FlatLine(f_start, f_p2).dot(line);

  const bool in_range = (t1 < mag) || (t2 < mag);
  // if at least one point is within range, capture both points

  AirspaceIntersectSort sorter(start, end, *this);
  if ((t1 >= fixed_zero) && in_range)
    sorter.add(t1 * inv_mag, projection.funproject(f_p1));

  if ((t2 >= fixed_zero) && in_range)
    sorter.add(t2 * inv_mag, projection.funproject(f_p2));

  return sorter.all();
}
示例#2
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);
}
示例#3
0
void
ThermalLocator::Update(const fixed t_0, 
                       const GeoPoint &location_0,
                       const SpeedVector wind, 
                       ThermalLocatorInfo &therm)
{
  if (n_points < TLOCATOR_NMIN) {
    therm.estimate_valid = false;
    return; // nothing to do.
  }

  GeoPoint dloc = FindLatitudeLongitude(location_0, wind.bearing, wind.norm);

  TaskProjection projection;
  projection.reset(location_0);
  projection.update_fast();

  // drift points 
  Drift(t_0, projection, location_0 - dloc);

  FlatPoint av = glider_average();
  // find thermal center relative to glider's average position

  FlatPoint f0(fixed_zero, fixed_zero);
  fixed acc = fixed_zero;
  for (unsigned i = 0; i < n_points; ++i) {
    f0 += (points[i].loc_drift-av)*points[i].lift_weight;
    acc += points[i].lift_weight;
  }

  // if sufficient data, estimate location

  if (!positive(acc)) {
    therm.estimate_valid = false;
    return;
  }
  f0 = f0 * (fixed_one/acc) + av;

  therm.estimate_location = projection.funproject(f0);
  therm.estimate_valid = true;
}