const SearchPointVector& AbstractAirspace::get_clearance() const { #define RADIUS 5 if (!m_clearance.empty()) return m_clearance; assert(m_task_projection != NULL); m_clearance = m_border; if (!m_is_convex) { prune_interior(m_clearance); } FlatBoundingBox bb = ::compute_boundingbox(m_clearance); FlatGeoPoint center = bb.get_center(); for (SearchPointVector::iterator i= m_clearance.begin(); i != m_clearance.end(); ++i) { FlatGeoPoint p = i->get_flatLocation(); FlatRay r(center, p); int mag = hypot(r.vector.Longitude, r.vector.Latitude); int mag_new = mag+RADIUS; p = r.parametric((fixed)mag_new/mag); *i = SearchPoint(m_task_projection->unproject(p)); i->project(*m_task_projection); } return m_clearance; }
bool SampledTaskPoint::update_sample_near(const AIRCRAFT_STATE& state, TaskEvents &task_events, const TaskProjection &projection) { if (isInSector(state)) { // if sample is inside sample polygon // return false (no update required) // else // add sample to polygon // re-compute convex hull // return true; (update required) // if (PolygonInterior(state.Location, m_sampled_points)) { // do nothing return false; } else { SearchPoint sp(state.Location, projection); m_sampled_points.push_back(sp); // only return true if hull changed bool retval = prune_interior(m_sampled_points); return thin_to_size(m_sampled_points, 64) || retval; // thin to size is used here to ensure the sampled points vector // size is bounded to reasonable values for AAT calculations. } } return false; }
bool AATPoint::update_sample_near(const AIRCRAFT_STATE& state, TaskEvents &task_events, const TaskProjection &projection) { bool retval = OrderedTaskPoint::update_sample_near(state, task_events, projection); if (retval) { // deadzone must be updated assert(get_next()); // the deadzone is the convex hull formed from the sampled points // with the inclusion of the destination of the next turnpoint. m_deadzone = SearchPointVector(get_sample_points().begin(), get_sample_points().end()); SearchPoint destination(get_next()->get_location_remaining(), projection); m_deadzone.push_back(destination); prune_interior(m_deadzone); } retval |= check_target(state, false); return retval; }
bool SampledTaskPoint::update_sample_near(const AIRCRAFT_STATE& state, TaskEvents &task_events, const TaskProjection &projection) { if (isInSector(state)) { // if sample is inside sample polygon // return false (no update required) // else // add sample to polygon // re-compute convex hull // return true; (update required) // if (PolygonInterior(state.Location, m_sampled_points)) { // do nothing return false; } else { SearchPoint sp(state.Location, projection); m_sampled_points.push_back(sp); // only return true if hull changed return prune_interior(m_sampled_points); } } return false; }
AirspacePolygon::AirspacePolygon(const std::vector<GeoPoint>& pts, const bool prune) :AbstractAirspace(POLYGON) { if (pts.size()<2) { m_is_convex = true; } else { TaskProjection task_projection; // note dummy blank projection for (std::vector<GeoPoint>::const_iterator v = pts.begin(); v != pts.end(); ++v) { m_border.push_back(SearchPoint(*v, task_projection)); } // ensure airspace is closed GeoPoint p_start = pts[0]; GeoPoint p_end = *(pts.end()-1); if (p_start != p_end) { m_border.push_back(SearchPoint(p_start, task_projection)); } if (prune) { // only for testing prune_interior(m_border); m_is_convex = true; } else { m_is_convex = is_convex(m_border); } } }
fixed OLCSISAT::calc_score() const { // build convex hull from solution SearchPointVector spv; for (unsigned i = 0; i < num_stages; ++i) spv.push_back(solution[i]); prune_interior(spv); // now add leg distances making up the convex hull fixed G = fixed_zero; if (spv.size() > 1) { for (unsigned i = 0; i + 1 < spv.size(); ++i) G += spv[i].distance(spv[i + 1].get_location()); // closing leg (end to start) G += spv[spv.size() - 1].distance(spv[0].get_location()); } // R distance (start to end) const fixed R = solution[0].distance(solution[num_stages - 1].get_location()); // V zigzag-free distance const fixed V = G - R; // S = total distance const fixed S = calc_distance(); return apply_handicap((V + fixed(3) * S) * fixed(0.00025)); }
void SampledTaskPoint::update_oz(const TaskProjection &projection) { m_search_max = m_search_reference; m_search_min = m_search_reference; m_boundary_points.clear(); if (m_boundary_scored) { for (fixed t=fixed_zero; t<= fixed_one; t+= fixed_steps) { SearchPoint sp(get_boundary_parametric(t)); m_boundary_points.push_back(sp); } prune_interior(m_boundary_points); } else { m_boundary_points.push_back(m_search_reference); } update_projection(projection); }
void AATPoint::update_deadzone(const TaskProjection &projection) { // deadzone must be updated assert(get_next()); assert(get_previous()); // the deadzone is the convex hull formed from the sampled points // with the inclusion of all points on the boundary closer than // the max double distance to the sample polygon m_deadzone = SearchPointVector(get_sample_points().begin(), get_sample_points().end()); // do nothing if no samples (could happen if not achieved properly) if (m_deadzone.empty()) return; // previous and next targets const SearchPoint pnext(get_next()->get_location_remaining(), projection); const SearchPoint pprevious(get_previous()->get_location_remaining(), projection); // find max distance unsigned dmax = 0; for (SearchPointVector::const_iterator it = get_sample_points().begin(); it != get_sample_points().end(); ++it) { unsigned dd = pnext.flat_distance(*it) + pprevious.flat_distance(*it); dmax = std::max(dd, dmax); } // now add boundary points closer than dmax const SearchPointVector& boundary = get_boundary_points(); for (SearchPointVector::const_iterator it = boundary.begin(); it != boundary.end(); ++it) { unsigned dd = pnext.flat_distance(*it) + pprevious.flat_distance(*it); if (dd< dmax) m_deadzone.push_back(*it); } // convert to convex polygon prune_interior(m_deadzone); }