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; }
GeoPoint AnnularSectorZone::GetBoundaryParametric(fixed t) const { const Angle sweep = (GetEndRadial() - GetStartRadial()).AsBearing(); const fixed c0 = sweep.Radians() * inner_radius; const fixed l = GetRadius() - inner_radius; const fixed c1 = sweep.Radians() * GetRadius(); const fixed tt = t * (c0 + c1 + 2 * l); Angle a; fixed d; if (tt < c0) { d = inner_radius; a = Angle::Radians((tt / c0) * sweep.Radians()) + GetStartRadial(); } else if (positive(l) && (tt < c0 + l)) { d = (tt - c0) / l * (GetRadius() - inner_radius) + inner_radius; a = GetEndRadial(); } else if (tt < c0 + l + c1) { d = GetRadius(); a = GetEndRadial() - Angle::Radians(((tt - c0 - l) / c1) * sweep.Radians()); } else if (positive(l)) { d = (tt - c0 - l - c1) / l * (inner_radius - GetRadius()) + GetRadius(); a = GetStartRadial(); } else { d = inner_radius; a = GetStartRadial(); } return GeoVector(d, a).EndPoint(GetReference()); }
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); }
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; }