IntersectingAirspaceVisitorAdapter(const GeoPoint &_loc, const GeoPoint &_end, const TaskProjection &_projection, AirspaceIntersectionVisitor &_visitor) :start(_loc), end(_end), projection(&_projection), ray(projection->ProjectInteger(start), projection->ProjectInteger(end)), visitor(&_visitor) {}
Airspace::Airspace(const GeoPoint &loc, const TaskProjection &task_projection, const fixed range) :FlatBoundingBox(task_projection.ProjectInteger(loc), task_projection.ProjectRangeInteger(loc, range)), airspace(nullptr) { }
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); }
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); }
/** * Constructor for virtual airspaces for use in range-based * intersection queries * * @param loc Location about which to create a virtual airspace envelope * @param task_projection projection to be used for flat-earth representation * @param range range in meters of virtual bounding box * * @return dummy airspace envelope */ Airspace(const GeoPoint&loc, const TaskProjection& task_projection, const fixed range=fixed_zero): FlatBoundingBox(task_projection.project(loc), task_projection.project_range(loc,range)), pimpl_airspace(NULL) { };
const FlatBoundingBox AirspaceCircle::get_bounding_box(const TaskProjection& task_projection) { static const Angle a225 = Angle::degrees(fixed(225)); static const Angle a135 = Angle::degrees(fixed(135)); static const Angle a045 = Angle::degrees(fixed(045)); static const Angle a315 = Angle::degrees(fixed(315)); const fixed eradius = m_radius * fixed(1.42); const GeoPoint ll = GeoVector(eradius, a225).end_point(m_center); const GeoPoint lr = GeoVector(eradius, a135).end_point(m_center); const GeoPoint ur = GeoVector(eradius, a045).end_point(m_center); const GeoPoint ul = GeoVector(eradius, a315).end_point(m_center); FlatGeoPoint fll = task_projection.project(ll); FlatGeoPoint flr = task_projection.project(lr); FlatGeoPoint ful = task_projection.project(ul); FlatGeoPoint fur = task_projection.project(ur); // note +/- 1 to ensure rounding keeps bb valid return FlatBoundingBox(FlatGeoPoint(min(fll.Longitude, ful.Longitude) - 1, min(fll.Latitude, flr.Latitude) - 1), FlatGeoPoint(max(flr.Longitude, fur.Longitude) + 1, max(ful.Latitude, fur.Latitude) + 1)); }
GeoPoint AirspacePolygon::ClosestPoint(const GeoPoint &loc, const TaskProjection &projection) const { const FlatGeoPoint p = projection.ProjectInteger(loc); const FlatGeoPoint pb = m_border.NearestPoint(p); return projection.Unproject(pb); }
void OrderedTaskPoint::ScanProjection(TaskProjection &task_projection) const { task_projection.Scan(GetLocation()); for (const auto &i : GetBoundary()) task_projection.Scan(i); }
void OrderedTaskPoint::scan_projection(TaskProjection& task_projection) const { task_projection.scan_location(get_location()); #define fixed_steps fixed(0.05) for (fixed t=fixed_zero; t<= fixed_one; t+= fixed_steps) { task_projection.scan_location(get_boundary_parametric(t)); } }
void OrderedTaskPoint::scan_projection(TaskProjection &task_projection) const { task_projection.scan_location(GetLocation()); #define fixed_steps fixed(0.05) const ObservationZone::Boundary boundary = GetBoundary(); for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i) task_projection.scan_location(*i); }
void ChartProjection::Set(const PixelRect &rc, const TaskProjection &task_projection, double radius_factor) { const GeoPoint center = task_projection.GetCenter(); const auto radius = std::max(double(10000), task_projection.ApproxRadius() * radius_factor); Set(rc, center, radius); }
void OrderedTaskPoint::UpdateBoundingBox(const TaskProjection &task_projection) { flat_bb = FlatBoundingBox(task_projection.ProjectInteger(GetLocation())); for (const auto &i : GetBoundary()) flat_bb.Expand(task_projection.ProjectInteger(i)); flat_bb.ExpandByOne(); // add 1 to fix rounding }
void OrderedTaskPoint::update_boundingbox(const TaskProjection& task_projection) { flat_bb = FlatBoundingBox(task_projection.project(get_location())); for (fixed t=fixed_zero; t<= fixed_one; t+= fixed_steps) flat_bb.expand(task_projection.project(get_boundary_parametric(t))); flat_bb.expand(); // add 1 to fix rounding }
void ChartProjection::Set(const PixelRect &rc, const TaskProjection &task_projection, fixed radius_factor) { const GeoPoint center = task_projection.get_center(); const fixed radius = max(fixed(10000), task_projection.ApproxRadius() * radius_factor); set_projection(rc, center, radius); }
void OrderedTaskPoint::update_boundingbox(const TaskProjection &task_projection) { flat_bb = FlatBoundingBox(task_projection.project(GetLocation())); const ObservationZone::Boundary boundary = GetBoundary(); for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i) flat_bb.Expand(task_projection.project(*i)); flat_bb.ExpandByOne(); // add 1 to fix rounding }
Airspace::Airspace(const GeoPoint &ll, const GeoPoint &ur, const TaskProjection &task_projection) :FlatBoundingBox(task_projection.ProjectInteger(ll), task_projection.ProjectInteger(ur)), airspace(nullptr) { }
void OrderedTaskPoint::update_boundingbox(const TaskProjection& task_projection) { FlatGeoPoint fmin; FlatGeoPoint fmax; bool empty = true; for (fixed t=fixed_zero; t<= fixed_one; t+= fixed_steps) { FlatGeoPoint f = task_projection.project(get_boundary_parametric(t)); if (empty) { empty = false; fmin = f; fmax = f; } else { fmin.Longitude = min(fmin.Longitude, f.Longitude); fmin.Latitude = min(fmin.Latitude, f.Latitude); fmax.Longitude = max(fmax.Longitude, f.Longitude); fmax.Latitude = max(fmax.Latitude, f.Latitude); } } // note +/- 1 to ensure rounding keeps bb valid fmin.Longitude-= 1; fmin.Latitude-= 1; fmax.Longitude+= 1; fmax.Latitude+= 1; flat_bb = FlatBoundingBox(fmin,fmax); }
SearchPoint::SearchPoint(const GeoPoint &loc, const TaskProjection &tp) :location(loc), flat_location(tp.ProjectInteger(loc)) #ifndef NDEBUG , projected(true) #endif { }
GeoPoint RoutePolars::MSLIntercept(const int index, const AGeoPoint& p, const TaskProjection& proj) const { const unsigned safe_index = ((unsigned)index) % ROUTEPOLAR_POINTS; const FlatGeoPoint fp = proj.ProjectInteger(p); const fixed d = p.altitude * polar_glide.GetPoint(safe_index).inv_gradient; const fixed scale = proj.GetApproximateScale(); const int steps = int(d / scale) + 1; int dx, dy; RoutePolar::IndexToDXDY(safe_index, dx, dy); dx = (dx * steps) >> 7; dy = (dy * steps) >> 7; const FlatGeoPoint dp(fp.longitude + dx, fp.latitude + dy); return proj.Unproject(dp); }
SearchPoint::SearchPoint(const FlatGeoPoint &floc, const TaskProjection &tp) :location(tp.Unproject(floc)), flat_location(floc) #ifndef NDEBUG , projected(true) #endif { }
/** * Constructor for virtual airspaces for use in bounding-box * specified intersection queries * * @param ll Lower left corner of bounding box * @param ur Upper right corner of bounding box * @param task_projection projection to be used for flat-earth representation * * @return dummy airspace envelope */ Airspace(const GeoPoint &ll, const GeoPoint &ur, const TaskProjection& task_projection): FlatBoundingBox(task_projection.project(ll), task_projection.project(ur)), pimpl_airspace(NULL) { };
void SearchPoint::Project(const TaskProjection &tp) { flat_location = tp.ProjectInteger(location); #ifndef NDEBUG projected = true; #endif }
void Waypoint::Project(const TaskProjection &task_projection) { flat_location = task_projection.ProjectInteger(location); #ifndef NDEBUG flat_location_initialised = true; #endif }
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(); }
bool RoutePolars::Intersection(const AGeoPoint& origin, const AGeoPoint& destination, const RasterMap* map, const TaskProjection& proj, GeoPoint& intx) const { if (map == nullptr || !map->IsDefined()) return false; RouteLink e(RoutePoint(proj.ProjectInteger(destination), destination.altitude), RoutePoint(proj.ProjectInteger(origin), origin.altitude), proj); if (!positive(e.d)) return false; const RoughAltitude vh = CalcVHeight(e); intx = map->Intersection(origin, (short)(origin.altitude - GetSafetyHeight()), (short)vh, destination); return !(intx == destination); }
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; }
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(); }
FlatGeoPoint RoutePolars::ReachIntercept(const int index, const AGeoPoint& origin, const RasterMap* map, const TaskProjection& proj) const { const bool valid = map && map->IsDefined(); const RoughAltitude altitude = origin.altitude - GetSafetyHeight(); const AGeoPoint m_origin((GeoPoint)origin, altitude); const GeoPoint dest = MSLIntercept(index, m_origin, proj); const GeoPoint p = valid ? map->Intersection(m_origin, (short)altitude, (short)altitude, dest) : dest; return proj.ProjectInteger(p); }
bool RoutePolars::CheckClearance(const RouteLink &e, const RasterMap* map, const TaskProjection &proj, RoutePoint& inp) const { if (!config.IsTerrainEnabled()) return true; GeoPoint int_x; int int_h; GeoPoint start = proj.Unproject(e.first); GeoPoint dest = proj.Unproject(e.second); assert(map); if (!map->FirstIntersection(start, (int)e.first.altitude, dest, (int)e.second.altitude, (int)CalcVHeight(e), (int)climb_ceiling, (int)GetSafetyHeight(), int_x, int_h)) return true; inp = RoutePoint(proj.ProjectInteger(int_x), RoughAltitude(int_h)); return false; }
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); }