AirspaceIntersectionVector AirspaceCircle::Intersects(const GeoPoint &start, const GeoPoint &end, const TaskProjection &projection) const { const fixed f_radius = projection.ProjectRangeFloat(m_center, m_radius); const FlatPoint f_center = projection.ProjectFloat(m_center); const FlatPoint f_start = projection.ProjectFloat(start); const FlatPoint f_end = projection.ProjectFloat(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(1) / mag; const fixed t1 = FlatLine(f_start, f_p1).dot(line); const fixed t2 = (f_p1 == f_p2) ? fixed(-1) : 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, *this); if ((t1 >= fixed(0)) && in_range) sorter.add(t1 * inv_mag, projection.Unproject(f_p1)); if ((t2 >= fixed(0)) && in_range) sorter.add(t2 * inv_mag, projection.Unproject(f_p2)); return sorter.all(); }
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); }
void AATPoint::SetTarget(RangeAndRadial rar, const TaskProjection &proj) { const FlatPoint fprev = proj.ProjectFloat(GetPrevious()->GetLocationRemaining()); const FlatPoint floc = proj.ProjectFloat(GetLocation()); const FlatLine flb (fprev,floc); const FlatLine fradius(floc, proj.ProjectFloat(negative(rar.range) ? GetLocationMin() : GetLocationMax())); const fixed radius = fradius.d() * fabs(rar.range); const Angle angle = rar.radial - flb.angle(); const FlatPoint ftarget1(radius * angle.cos(), radius * -(angle).sin()); const FlatPoint ftarget2 = floc + ftarget1; const GeoPoint targetG = proj.Unproject(ftarget2); SetTarget(targetG, true); }
inline void ThermalLocator::Point::Drift(fixed t, const TaskProjection& projection, const GeoPoint& wind_drift) { const fixed dt = t - t_0; // thermal decay function is located in GenerateSineTables.cpp recency_weight = thermal_recency_fn((unsigned)fabs(dt)); lift_weight = w*recency_weight; GeoPoint p = location + wind_drift * dt; // convert to flat earth coordinates loc_drift = projection.ProjectFloat(p); }