AirspaceIntersectionVector AirspaceCircle::intersects(const GeoPoint& start, const GeoVector &vec) const { const GeoPoint end = vec.end_point(start); AirspaceIntersectSort sorter(start, end, *this); const fixed f_radius = m_task_projection->fproject_range(m_center, m_radius); const FlatPoint f_center = m_task_projection->fproject(m_center); const FlatPoint f_start = m_task_projection->fproject(start); const FlatPoint f_end = m_task_projection->fproject(end); const FlatLine line(f_start, f_end); if (inside(start)) sorter.add(fixed_zero, start); FlatPoint f_p1, f_p2; if (line.intersect_circle(f_radius, f_center, f_p1, f_p2)) { const fixed mag = line.mag_sq(); if (positive(mag)) { fixed inv_mag = -fixed_one; 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 if ((t1 >= fixed_zero) && in_range) { if (negative(inv_mag)) inv_mag = fixed_one / mag; sorter.add(t1 * inv_mag, m_task_projection->funproject(f_p1)); } if ((t2 >= fixed_zero) && in_range) { if (negative(inv_mag)) inv_mag = fixed_one / mag; sorter.add(t2 * inv_mag, m_task_projection->funproject(f_p2)); } } } return sorter.all(); }
void Airspaces::visit_intersecting(const GeoPoint &loc, const GeoVector &vec, AirspaceIntersectionVisitor& visitor) const { FlatRay ray(task_projection.project(loc), task_projection.project(vec.end_point(loc))); GeoPoint c = vec.mid_point(loc); Airspace bb_target(c, task_projection); int mrange = task_projection.project_range(c, vec.Distance / 2); IntersectingAirspaceVisitorAdapter adapter(loc, vec, ray, visitor); airspace_tree.visit_within_range(bb_target, -mrange, adapter); #ifdef INSTRUMENT_TASK n_queries++; #endif }
AirspaceIntersectionVector AirspacePolygon::intersects(const GeoPoint& start, const GeoVector &vec) const { const GeoPoint end = vec.end_point(start); const FlatRay ray(m_task_projection->project(start), m_task_projection->project(end)); AirspaceIntersectSort sorter(start, end, *this); for (SearchPointVector::const_iterator it= m_border.begin(); it+1 != m_border.end(); ++it) { const FlatRay r_seg(it->get_flatLocation(), (it+1)->get_flatLocation()); const fixed t = ray.intersects(r_seg); if (t>=fixed_zero) { sorter.add(t, m_task_projection->unproject(ray.parametric(t))); } } return sorter.all(); }