bool PolygonInterior(const FlatGeoPoint &P, SearchPointVector::const_iterator begin, SearchPointVector::const_iterator end) { if (std::distance(begin, end) < 3) return false; int wn = 0; // the winding number counter // loop through all edges of the polygon for (auto i = begin, next = std::next(i); next != end; i = next, next = std::next(i)) { // edge from current to next if (i->GetFlatLocation().y <= P.y) { // start y <= P.y if (next->GetFlatLocation().y > P.y) // an upward crossing if (isLeft(i->GetFlatLocation(), next->GetFlatLocation(), P) > 0) // P left of edge // have a valid up intersect ++wn; } else { // start y > P.y (no test needed) if (next->GetFlatLocation().y <= P.y) // a downward crossing if (isLeft(i->GetFlatLocation(), next->GetFlatLocation(), P) < 0) // P right of edge // have a valid down intersect --wn; } } return wn != 0; }
bool SearchPointVector::IntersectsWith(const FlatRay &ray) const { for (auto it = begin(); it + 1 != end(); ++it) { const FlatRay r_seg(it->GetFlatLocation(), (it + 1)->GetFlatLocation()); if (r_seg.IntersectsDistinct(ray)) return true; } return false; }
SearchPointVector::const_iterator SearchPointVector::NearestIndexConvex(const FlatGeoPoint &p3) const { unsigned distance_min = 0 - 1; const_iterator i_best = end(); // find nearest point in vector for (auto i = begin(); i != end(); ++i) { unsigned d_this = p3.DistanceSquared(i->GetFlatLocation()); if (d_this < distance_min) { distance_min = d_this; i_best = i; } } return i_best; }
AirspaceIntersectionVector AirspacePolygon::Intersects(const GeoPoint &start, const GeoPoint &end, const TaskProjection &projection) const { const FlatRay ray(projection.ProjectInteger(start), projection.ProjectInteger(end)); AirspaceIntersectSort sorter(start, *this); for (auto it = m_border.begin(); it + 1 != m_border.end(); ++it) { const FlatRay r_seg(it->GetFlatLocation(), (it + 1)->GetFlatLocation()); fixed t = ray.DistinctIntersection(r_seg); if (!negative(t)) sorter.add(t, projection.Unproject(ray.Parametric(t))); } return sorter.all(); }