void StartPoint::find_best_start(const AircraftState &state, const OrderedTaskPoint &next, const TaskProjection &projection) { /* check which boundary point results in the smallest distance to fly */ const OZBoundary boundary = next.GetBoundary(); assert(!boundary.empty()); const auto end = boundary.end(); auto i = boundary.begin(); assert(i != end); const GeoPoint &next_location = next.GetLocationRemaining(); GeoPoint best_location = *i; fixed best_distance = ::DoubleDistance(state.location, *i, next_location); for (++i; i != end; ++i) { fixed distance = ::DoubleDistance(state.location, *i, next_location); if (distance < best_distance) { best_location = *i; best_distance = distance; } } SetSearchMin(SearchPoint(best_location, projection)); }
OZBoundary FAISectorZone::GetBoundary() const { OZBoundary boundary; boundary.push_front(GetSectorEnd()); boundary.push_front(GetSectorStart()); boundary.push_front(GetReference()); return boundary; }
OZBoundary SectorZone::GetBoundary() const { OZBoundary boundary; boundary.push_front(GetReference()); boundary.push_front(GetSectorStart()); boundary.push_front(GetSectorEnd()); boundary.GenerateArcExcluding(GetReference(), GetRadius(), GetStartRadial(), GetEndRadial()); return boundary; }
OZBoundary CylinderZone::GetBoundary() const { OZBoundary boundary; const unsigned steps = 20; const Angle delta = Angle::FullCircle() / steps; GeoVector vector(GetRadius(), Angle::Zero()); for (unsigned i = 0; i < steps; ++i, vector.bearing += delta) boundary.push_front(vector.EndPoint(GetReference())); return boundary; }
OZBoundary AnnularSectorZone::GetBoundary() const { OZBoundary boundary; const unsigned steps = 20; const Angle delta = Angle::FullCircle() / steps; const Angle start = GetStartRadial().AsBearing(); Angle end = GetEndRadial().AsBearing(); if (end <= start + Angle::FullCircle() / 512) end += Angle::FullCircle(); const GeoPoint inner_start = GeoVector(GetInnerRadius(), GetStartRadial()).EndPoint(GetReference()); const GeoPoint inner_end = GeoVector(GetInnerRadius(), GetEndRadial()).EndPoint(GetReference()); GeoVector inner_vector(GetInnerRadius(), start + delta); for (; inner_vector.bearing < end; inner_vector.bearing += delta) boundary.push_front(inner_vector.EndPoint(GetReference())); boundary.push_front(inner_end); boundary.push_front(inner_start); GeoVector vector(GetRadius(), start + delta); for (; vector.bearing < end; vector.bearing += delta) boundary.push_front(vector.EndPoint(GetReference())); boundary.push_front(GetSectorEnd()); boundary.push_front(GetSectorStart()); return boundary; }
void OZPreviewRenderer::Draw(Canvas &canvas, const ObservationZonePoint &oz, const RasterPoint pt, unsigned radius, const TaskLook &look, const AirspaceRendererSettings &airspace_settings, const AirspaceLook &airspace_look) { fixed scale; GeoPoint center; if (IsAncientHardware()) { scale = fixed(radius) / ((const CylinderZone &)oz).GetRadius(); center = oz.GetReference(); } else { OZBoundary boundary = oz.GetBoundary(); auto it = boundary.begin(); GeoBounds bounds(*it); for (auto it_end = boundary.end(); it != it_end; ++it) bounds.Extend(*it); center = bounds.GetCenter(); fixed geo_heigth = GeoPoint(center.longitude, bounds.north).Distance( GeoPoint(center.longitude, bounds.south)); fixed geo_width = GeoPoint(bounds.west, center.latitude).Distance( GeoPoint(bounds.east, center.latitude)); scale = fixed(radius * 2) / std::max(geo_heigth, geo_width); } WindowProjection projection; projection.SetScreenSize(radius * 2, radius * 2); projection.SetScreenOrigin(pt.x, pt.y); projection.SetGeoLocation(center); projection.SetScale(scale); projection.SetScreenAngle(Angle::Zero()); projection.UpdateScreenBounds(); OZRenderer ozv(look, airspace_look, airspace_settings); ozv.Draw(canvas, OZRenderer::LAYER_SHADE, projection, oz, 1); ozv.Draw(canvas, OZRenderer::LAYER_INACTIVE, projection, oz, 1); ozv.Draw(canvas, OZRenderer::LAYER_ACTIVE, projection, oz, 1); }
void OZPreviewRenderer::Draw(Canvas &canvas, const ObservationZonePoint &oz, const PixelPoint pt, unsigned radius, const TaskLook &look, const AirspaceRendererSettings &airspace_settings, const AirspaceLook &airspace_look) { double scale; GeoPoint center; if (IsAncientHardware()) { scale = double(radius) / ((const CylinderZone &)oz).GetRadius(); center = oz.GetReference(); } else { OZBoundary boundary = oz.GetBoundary(); GeoBounds bounds = GeoBounds::Invalid(); for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i) bounds.Extend(*i); center = bounds.GetCenter(); auto geo_width = bounds.GetGeoWidth(); auto geo_heigth = bounds.GetGeoHeight(); scale = double(radius * 2) / std::max(geo_heigth, geo_width); } WindowProjection projection; projection.SetScreenSize({radius * 2, radius * 2}); projection.SetScreenOrigin(pt.x, pt.y); projection.SetGeoLocation(center); projection.SetScale(scale); projection.SetScreenAngle(Angle::Zero()); projection.UpdateScreenBounds(); OZRenderer ozv(look, airspace_look, airspace_settings); ozv.Draw(canvas, OZRenderer::LAYER_SHADE, projection, oz, 1); ozv.Draw(canvas, OZRenderer::LAYER_INACTIVE, projection, oz, 1); ozv.Draw(canvas, OZRenderer::LAYER_ACTIVE, projection, oz, 1); }
void SampledTaskPoint::UpdateOZ(const TaskProjection &projection) { search_max = search_reference; search_min = search_reference; boundary_points.clear(); if (boundary_scored) { const OZBoundary boundary = GetBoundary(); for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i) { SearchPoint sp(*i); boundary_points.push_back(sp); } boundary_points.PruneInterior(); } else { boundary_points.push_back(search_reference); } UpdateProjection(projection); }
void OZWindow::OnPaint(Canvas &canvas) { canvas.ClearWhite(); if (oz == NULL) return; const int offset = 0; roz.Draw(canvas, OZRenderer::LAYER_SHADE, projection, *oz, offset); roz.Draw(canvas, OZRenderer::LAYER_INACTIVE, projection, *oz, offset); roz.Draw(canvas, OZRenderer::LAYER_ACTIVE, projection, *oz, offset); /* debugging for ObservationZone::GetBoundary() */ Pen pen(1, COLOR_RED); canvas.Select(pen); const OZBoundary boundary = oz->GetBoundary(); for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i) { RasterPoint p = projection.GeoToScreen(*i); canvas.DrawLine(p.x - 3, p.y - 3, p.x + 3, p.y + 3); canvas.DrawLine(p.x + 3, p.y - 3, p.x - 3, p.y + 3); } }
OZBoundary KeyholeZone::GetBoundary() const { OZBoundary boundary; boundary.push_front(GetSectorStart()); boundary.push_front(GetSectorEnd()); boundary.GenerateArcExcluding(GetReference(), GetRadius(), GetStartRadial(), GetEndRadial()); const fixed small_radius = GetInnerRadius(); GeoVector small_vector(small_radius, GetStartRadial()); boundary.push_front(small_vector.EndPoint(GetReference())); small_vector.bearing = GetEndRadial(); boundary.push_front(small_vector.EndPoint(GetReference())); boundary.GenerateArcExcluding(GetReference(), small_radius, GetEndRadial(), GetStartRadial()); return std::move(boundary); }