LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
lsst::sphgeom::Circle Class Reference

Circle is a circular region on the unit sphere that contains its boundary. More...

#include <Circle.h>

Inheritance diagram for lsst::sphgeom::Circle:
lsst::sphgeom::Region

Public Member Functions

 Circle ()
 This constructor creates an empty circle. More...
 
 Circle (UnitVector3d const &c)
 This constructor creates the circle with center c and squared chord length / opening angle of zero. More...
 
 Circle (UnitVector3d const &c, Angle a)
 This constructor creates a circle with center c and opening angle a. More...
 
 Circle (UnitVector3d const &c, double cl2)
 This constructor creates a circle with center c and squared chord length cl2. More...
 
bool operator== (Circle const &c) const
 
bool operator!= (Circle const &c) const
 
bool isEmpty () const
 
bool isFull () const
 
UnitVector3d const & getCenter () const
 getCenter returns the center of this circle as a unit vector. More...
 
double getSquaredChordLength () const
 getSquaredChordLength returns the squared length of chords between the circle center and points on the circle boundary. More...
 
Angle getOpeningAngle () const
 getOpeningAngle returns the opening angle of this circle - that is, the angle between its center vector and points on its boundary. More...
 
bool contains (Circle const &x) const
 contains returns true if the intersection of this circle and x is equal to x. More...
 
CircledilateBy (Angle r)
 If r is positive, dilateBy increases the opening angle of this circle to include all points within angle r of its boundary. More...
 
Circle dilatedBy (Angle r) const
 
CircleerodeBy (Angle r)
 
Circle erodedBy (Angle r) const
 
double getArea () const
 getArea returns the area of this circle in steradians. More...
 
Circlecomplement ()
 complement sets this circle to the closure of its complement. More...
 
Circle complemented () const
 complemented returns the closure of the complement of this circle. More...
 
Relationship relate (UnitVector3d const &v) const
 
std::unique_ptr< Regionclone () const override
 clone returns a deep copy of this region. More...
 
Box getBoundingBox () const override
 getBoundingBox returns a bounding-box for this region. More...
 
Box3d getBoundingBox3d () const override
 getBoundingBox3d returns a 3-dimensional bounding-box for this region. More...
 
Circle getBoundingCircle () const override
 getBoundingCircle returns a bounding-circle for this region. More...
 
bool contains (UnitVector3d const &v) const override
 contains tests whether the given unit vector is inside this region. More...
 
Relationship relate (Region const &r) const override
 
Relationship relate (Box const &) const override
 
Relationship relate (Circle const &) const override
 
Relationship relate (ConvexPolygon const &) const override
 
Relationship relate (Ellipse const &) const override
 
std::vector< uint8_t > encode () const override
 encode serializes this region into an opaque byte string. More...
 
virtual bool contains (UnitVector3d const &) const=0
 contains tests whether the given unit vector is inside this region. More...
 
bool contains (double x, double y, double z) const
 contains tests whether the unit vector defined by the given (not necessarily normalized) coordinates is inside this region. More...
 
bool contains (double lon, double lat) const
 contains tests whether the unit vector defined by the given longitude and latitude coordinates (in radians) is inside this region. More...
 
bool isDisjointFrom (UnitVector3d const &x) const
 
bool isDisjointFrom (Circle const &x) const
 
bool intersects (UnitVector3d const &x) const
 
bool intersects (Circle const &x) const
 
bool isWithin (UnitVector3d const &) const
 
bool isWithin (Circle const &x) const
 
CircleclipTo (UnitVector3d const &x)
 
CircleclipTo (Circle const &x)
 
Circle clippedTo (UnitVector3d const &x) const
 
Circle clippedTo (Circle const &x) const
 
CircleexpandTo (UnitVector3d const &x)
 
CircleexpandTo (Circle const &x)
 
Circle expandedTo (UnitVector3d const &x) const
 
Circle expandedTo (Circle const &x) const
 

Static Public Member Functions

static Circle empty ()
 
static Circle full ()
 
static double squaredChordLengthFor (Angle openingAngle)
 squaredChordLengthFor computes and returns the squared chord length between points in S² that are separated by the given angle. More...
 
static Angle openingAngleFor (double squaredChordLength)
 openingAngleFor computes and returns the angular separation between points in S² that are separated by the given squared chord length. More...
 
static std::unique_ptr< Circledecode (std::vector< uint8_t > const &s)
 
static std::unique_ptr< Circledecode (uint8_t const *buffer, size_t n)
 

Static Public Attributes

static constexpr uint8_t TYPE_CODE = 'c'
 

Detailed Description

Circle is a circular region on the unit sphere that contains its boundary.

Internally, the circle is represented by its center vector and the squared length of the chords between its center and points on its boundary. This yields a fast point-in-circle test but, unlike a representation that uses the center vector and cosine of the circle opening angle, remains accurate for circles with very small opening angles.

Definition at line 46 of file Circle.h.

Constructor & Destructor Documentation

◆ Circle() [1/4]

lsst::sphgeom::Circle::Circle ( )
inline

This constructor creates an empty circle.

Definition at line 65 of file Circle.h.

65 :
66 _center(UnitVector3d::Z()),
67 _squaredChordLength(-1.0),
68 _openingAngle(-1.0)
69 {}
static UnitVector3d Z()
Definition: UnitVector3d.h:101

◆ Circle() [2/4]

lsst::sphgeom::Circle::Circle ( UnitVector3d const &  c)
inlineexplicit

This constructor creates the circle with center c and squared chord length / opening angle of zero.

Because of rounding error, (v - c).squaredNorm() == 0.0 does not imply that v == c. Therefore calling contains(v) on the resulting circle may return true for unit vectors v != c.

Definition at line 76 of file Circle.h.

76 :
77 _center(c),
78 _squaredChordLength(0.0),
79 _openingAngle(0.0)
80 {}

◆ Circle() [3/4]

lsst::sphgeom::Circle::Circle ( UnitVector3d const &  c,
Angle  a 
)
inline

This constructor creates a circle with center c and opening angle a.

If a is negative or NaN, the circle will be empty, and if a is greater than or equal to PI, the circle will be full.

Definition at line 85 of file Circle.h.

85 :
86 _center(c),
87 _squaredChordLength(squaredChordLengthFor(a)),
88 _openingAngle(a)
89 {}
table::Key< int > a
static double squaredChordLengthFor(Angle openingAngle)
squaredChordLengthFor computes and returns the squared chord length between points in S² that are sep...
Definition: Circle.cc:41

◆ Circle() [4/4]

lsst::sphgeom::Circle::Circle ( UnitVector3d const &  c,
double  cl2 
)
inline

This constructor creates a circle with center c and squared chord length cl2.

If cl2 is negative or NaN, the circle will be empty, and if cl2 is greater than or equal to 4, the circle will be full.

Definition at line 94 of file Circle.h.

94 :
95 _center(c),
96 _squaredChordLength(cl2),
97 _openingAngle(openingAngleFor(cl2))
98 {}
static Angle openingAngleFor(double squaredChordLength)
openingAngleFor computes and returns the angular separation between points in S² that are separated b...
Definition: Circle.cc:52

Member Function Documentation

◆ clippedTo() [1/2]

Circle lsst::sphgeom::Circle::clippedTo ( Circle const &  x) const
inline

clippedTo returns the minimal bounding circle for the intersection of this circle and x.

Definition at line 169 of file Circle.h.

169 {
170 return Circle(*this).clipTo(x);
171 }
double x
Circle()
This constructor creates an empty circle.
Definition: Circle.h:65

◆ clippedTo() [2/2]

Circle lsst::sphgeom::Circle::clippedTo ( UnitVector3d const &  x) const
inline

clippedTo returns the minimal bounding circle for the intersection of this circle and x.

Definition at line 165 of file Circle.h.

165 {
166 return Circle(*this).clipTo(x);
167 }

◆ clipTo() [1/2]

Circle & lsst::sphgeom::Circle::clipTo ( Circle const &  x)

clipTo sets this circle to the minimal bounding circle for the intersection of this circle and x.

Definition at line 96 of file Circle.cc.

96 {
97 if (isEmpty() || x.isFull()) {
98 return *this;
99 }
100 if (isFull() || x.isEmpty()) {
101 *this = x;
102 return *this;
103 }
104 Angle a = _openingAngle;
105 Angle b = x._openingAngle;
106 NormalizedAngle cc(_center, x._center);
107 if (cc > a + b + 4.0 * Angle(MAX_ASIN_ERROR)) {
108 // This circle is disjoint from x.
109 *this = empty();
110 return *this;
111 }
112 // The circles (nearly) intersect, or one contains the other.
113 // For now, take the easy route and just use the smaller of
114 // the two circles as a bound on their intersection.
115 //
116 // TODO(smm): Compute the minimal bounding circle.
117 if (b < a) {
118 *this = x;
119 }
120 return *this;
121}
table::Key< int > b
bool isEmpty() const
Definition: Circle.h:109
static Circle empty()
Definition: Circle.h:50
bool isFull() const
Definition: Circle.h:114
lsst::geom::Angle Angle
Definition: misc.h:33
constexpr double MAX_ASIN_ERROR
Definition: constants.h:45

◆ clipTo() [2/2]

Circle & lsst::sphgeom::Circle::clipTo ( UnitVector3d const &  x)

clipTo sets this circle to the minimal bounding circle for the intersection of this circle and x.

Definition at line 91 of file Circle.cc.

91 {
92 *this = contains(x) ? Circle(x) : empty();
93 return *this;
94}
bool contains(Circle const &x) const
contains returns true if the intersection of this circle and x is equal to x.
Definition: Circle.cc:64

◆ clone()

std::unique_ptr< Region > lsst::sphgeom::Circle::clone ( ) const
inlineoverridevirtual

clone returns a deep copy of this region.

Implements lsst::sphgeom::Region.

Definition at line 222 of file Circle.h.

222 {
223 return std::unique_ptr<Circle>(new Circle(*this));
224 }

◆ complement()

Circle & lsst::sphgeom::Circle::complement ( )

complement sets this circle to the closure of its complement.

Note that both the empty circle as well as all circles containing a single point are mapped to a full circle, so that taking the complement of a circle twice is not guaranteed to reproduce the original circle, even in the absence of rounding error.

Definition at line 197 of file Circle.cc.

197 {
198 if (isEmpty()) {
199 // The complement of an empty circle is a full circle.
200 _squaredChordLength = 4.0;
201 _openingAngle = Angle(PI);
202 } else if (isFull()) {
203 // The complement of a full circle is an empty circle.
204 _squaredChordLength = -1.0;
205 _openingAngle = Angle(-1.0);
206 } else {
207 _center = -_center;
208 _squaredChordLength = 4.0 - _squaredChordLength;
209 _openingAngle = Angle(PI) - _openingAngle;
210 }
211 return *this;
212}
constexpr double PI
Definition: constants.h:36

◆ complemented()

Circle lsst::sphgeom::Circle::complemented ( ) const
inline

complemented returns the closure of the complement of this circle.

Definition at line 217 of file Circle.h.

217{ return Circle(*this).complement(); }

◆ contains() [1/5]

bool lsst::sphgeom::Circle::contains ( Circle const &  x) const

contains returns true if the intersection of this circle and x is equal to x.

Definition at line 64 of file Circle.cc.

64 {
65 if (isFull() || x.isEmpty()) {
66 return true;
67 }
68 if (isEmpty() || x.isFull()) {
69 return false;
70 }
71 if (*this == x) {
72 return true;
73 }
74 NormalizedAngle cc(_center, x._center);
75 return _openingAngle >
76 cc + x._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR);
77}

◆ contains() [2/5]

bool lsst::sphgeom::Region::contains ( double  lon,
double  lat 
) const

contains tests whether the unit vector defined by the given longitude and latitude coordinates (in radians) is inside this region.

Definition at line 104 of file Region.cc.

44 {
45 return contains(UnitVector3d(LonLat::fromRadians(lon, lat)));
46}
static LonLat fromRadians(double lon, double lat)
Definition: LonLat.h:55

◆ contains() [3/5]

bool lsst::sphgeom::Region::contains ( double  x,
double  y,
double  z 
) const

contains tests whether the unit vector defined by the given (not necessarily normalized) coordinates is inside this region.

Definition at line 100 of file Region.cc.

40 {
41 return contains(UnitVector3d(x, y, z));
42}
double z
Definition: Match.cc:44
int y
Definition: SpanSet.cc:48

◆ contains() [4/5]

virtual bool lsst::sphgeom::Region::contains ( UnitVector3d const &  ) const
virtual

contains tests whether the given unit vector is inside this region.

Implements lsst::sphgeom::Region.

◆ contains() [5/5]

bool lsst::sphgeom::Circle::contains ( UnitVector3d const &  ) const
inlineoverridevirtual

contains tests whether the given unit vector is inside this region.

Implements lsst::sphgeom::Region.

Definition at line 230 of file Circle.h.

230 {
231 return isFull() ||
232 (v - _center).getSquaredNorm() <= _squaredChordLength;
233 }

◆ decode() [1/2]

static std::unique_ptr< Circle > lsst::sphgeom::Circle::decode ( std::vector< uint8_t > const &  s)
inlinestatic

decode deserializes a Circle from a byte string produced by encode.

Definition at line 251 of file Circle.h.

251 {
252 return decode(s.data(), s.size());
253 }
static std::unique_ptr< Circle > decode(std::vector< uint8_t > const &s)
Definition: Circle.h:251
T data(T... args)
T size(T... args)

◆ decode() [2/2]

std::unique_ptr< Circle > lsst::sphgeom::Circle::decode ( uint8_t const *  buffer,
size_t  n 
)
static

decode deserializes a Circle from a byte string produced by encode.

Definition at line 345 of file Circle.cc.

345 {
346 if (buffer == nullptr || n != ENCODED_SIZE || *buffer != TYPE_CODE) {
347 throw std::runtime_error("Byte-string is not an encoded Circle");
348 }
350 ++buffer;
351 double x = decodeDouble(buffer); buffer += 8;
352 double y = decodeDouble(buffer); buffer += 8;
353 double z = decodeDouble(buffer); buffer += 8;
354 double squaredChordLength = decodeDouble(buffer); buffer += 8;
355 double openingAngle = decodeDouble(buffer); buffer += 8;
356 circle->_center = UnitVector3d::fromNormalized(x, y, z);
357 circle->_squaredChordLength = squaredChordLength;
358 circle->_openingAngle = Angle(openingAngle);
359 return circle;
360}
static constexpr uint8_t TYPE_CODE
Definition: Circle.h:48
static UnitVector3d fromNormalized(Vector3d const &v)
fromNormalized returns the unit vector equal to v, which is assumed to be normalized.
Definition: UnitVector3d.h:82
double decodeDouble(uint8_t const *buffer)
decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
Definition: codec.h:66

◆ dilateBy()

Circle & lsst::sphgeom::Circle::dilateBy ( Angle  r)

If r is positive, dilateBy increases the opening angle of this circle to include all points within angle r of its boundary.

If r is negative, it decreases the opening angle to exclude those points instead.

If this circle is empty or full, or r is zero or NaN, there is no effect.

Definition at line 187 of file Circle.cc.

187 {
188 if (!isEmpty() && !isFull() &&
189 (r.asRadians() > 0.0 || r.asRadians() < 0.0)) {
190 Angle o = _openingAngle + r;
191 _squaredChordLength = squaredChordLengthFor(o);
192 _openingAngle = o;
193 }
194 return *this;
195}

◆ dilatedBy()

Circle lsst::sphgeom::Circle::dilatedBy ( Angle  r) const
inline

Definition at line 200 of file Circle.h.

200{ return Circle(*this).dilateBy(r); }

◆ empty()

static Circle lsst::sphgeom::Circle::empty ( )
inlinestatic

Definition at line 50 of file Circle.h.

50{ return Circle(); }

◆ encode()

std::vector< uint8_t > lsst::sphgeom::Circle::encode ( ) const
overridevirtual

encode serializes this region into an opaque byte string.

Byte strings emitted by encode can be deserialized with decode.

Implements lsst::sphgeom::Region.

Definition at line 332 of file Circle.cc.

332 {
334 uint8_t tc = TYPE_CODE;
335 buffer.reserve(ENCODED_SIZE);
336 buffer.push_back(tc);
337 encodeDouble(_center.x(), buffer);
338 encodeDouble(_center.y(), buffer);
339 encodeDouble(_center.z(), buffer);
340 encodeDouble(_squaredChordLength, buffer);
341 encodeDouble(_openingAngle.asRadians(), buffer);
342 return buffer;
343}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition: Angle.h:85
void encodeDouble(double item, std::vector< uint8_t > &buffer)
encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.
Definition: codec.h:46
T push_back(T... args)
T reserve(T... args)

◆ erodeBy()

Circle & lsst::sphgeom::Circle::erodeBy ( Angle  r)
inline

Definition at line 201 of file Circle.h.

201{ return dilateBy(-r); }
Circle & dilateBy(Angle r)
If r is positive, dilateBy increases the opening angle of this circle to include all points within an...
Definition: Circle.cc:187

◆ erodedBy()

Circle lsst::sphgeom::Circle::erodedBy ( Angle  r) const
inline

Definition at line 202 of file Circle.h.

202{ return dilatedBy(-r); }
Circle dilatedBy(Angle r) const
Definition: Circle.h:200

◆ expandedTo() [1/2]

Circle lsst::sphgeom::Circle::expandedTo ( Circle const &  x) const
inline

expandedTo returns the minimal bounding circle for the union of this circle and x.

Definition at line 187 of file Circle.h.

187 {
188 return Circle(*this).expandTo(x);
189 }

◆ expandedTo() [2/2]

Circle lsst::sphgeom::Circle::expandedTo ( UnitVector3d const &  x) const
inline

expandedTo returns the minimal bounding circle for the union of this circle and x.

Definition at line 183 of file Circle.h.

183 {
184 return Circle(*this).expandTo(x);
185 }

◆ expandTo() [1/2]

Circle & lsst::sphgeom::Circle::expandTo ( Circle const &  x)

expandTo minimally expands this circle to contain x.

Definition at line 147 of file Circle.cc.

147 {
148 if (isEmpty() || x.isFull()) {
149 *this = x;
150 return *this;
151 }
152 if (x.isEmpty() || isFull()) {
153 return *this;
154 }
155 NormalizedAngle cc(_center, x._center);
156 if (cc + x._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <= _openingAngle) {
157 // This circle contains x.
158 return *this;
159 }
160 if (cc + _openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <= x._openingAngle) {
161 // x contains this circle.
162 *this = x;
163 return *this;
164 }
165 // The circles intersect or are disjoint.
166 Angle o = 0.5 * (cc + _openingAngle + x._openingAngle);
167 if (o + 2.0 * Angle(MAX_ASIN_ERROR) >= Angle(PI)) {
168 *this = full();
169 return *this;
170 }
171 // Compute the normal vector for the plane defined by the circle centers.
172 UnitVector3d n = UnitVector3d::orthogonalTo(_center, x._center);
173 // The minimal bounding circle (MBC) includes unit vectors on the plane
174 // with normal n that span from _center.rotatedAround(n, -_openingAngle)
175 // to x._center.rotatedAround(n, x._openingAngle). The MBC center is the
176 // midpoint of this interval.
177 Angle r = o - _openingAngle;
178 // Rotate _center by angle r around n to obtain the MBC center. This is
179 // done using Rodriques' formula, simplified by taking advantage of the
180 // orthogonality of _center and n.
181 _center = UnitVector3d(_center * cos(r) + n.cross(_center) * sin(r));
182 _squaredChordLength = squaredChordLengthFor(o + Angle(MAX_ASIN_ERROR));
183 _openingAngle = o + Angle(MAX_ASIN_ERROR);
184 return *this;
185}
static Circle full()
Definition: Circle.h:52
static UnitVector3d orthogonalTo(Vector3d const &v)
orthogonalTo returns an arbitrary unit vector that is orthogonal to v.
Definition: UnitVector3d.cc:34
double sin(Angle const &a)
Definition: Angle.h:102
double cos(Angle const &a)
Definition: Angle.h:103

◆ expandTo() [2/2]

Circle & lsst::sphgeom::Circle::expandTo ( UnitVector3d const &  x)

expandTo minimally expands this circle to contain x.

Definition at line 123 of file Circle.cc.

123 {
124 // For any circle c and unit vector x, c.expandTo(x).contains(x)
125 // should return true.
126 if (isEmpty()) {
127 *this = Circle(x);
128 } else if (!contains(x)) {
129 // Compute the normal vector for the plane defined by _center and x.
130 UnitVector3d n = UnitVector3d::orthogonalTo(_center, x);
131 // The minimal bounding circle (MBC) includes unit vectors on the plane
132 // with normal n that span from _center.rotatedAround(n, -_openingAngle)
133 // to x. The MBC center is the midpoint of this interval.
134 NormalizedAngle cx(_center, x);
135 Angle o = 0.5 * (cx + _openingAngle);
136 Angle r = 0.5 * (cx - _openingAngle);
137 // Rotate _center by angle r around n to obtain the MBC center. This is
138 // done using Rodriques' formula, simplified by taking advantage of the
139 // orthogonality of _center and n.
140 _center = UnitVector3d(_center * cos(r) + n.cross(_center) * sin(r));
141 _squaredChordLength = squaredChordLengthFor(o + Angle(MAX_ASIN_ERROR));
142 _openingAngle = o + Angle(MAX_ASIN_ERROR);
143 }
144 return *this;
145}

◆ full()

static Circle lsst::sphgeom::Circle::full ( )
inlinestatic

Definition at line 52 of file Circle.h.

52{ return Circle(UnitVector3d::Z(), 4.0); }

◆ getArea()

double lsst::sphgeom::Circle::getArea ( ) const
inline

getArea returns the area of this circle in steradians.

Definition at line 205 of file Circle.h.

205 {
206 return PI * std::max(0.0, std::min(_squaredChordLength, 4.0));
207 }
T max(T... args)
T min(T... args)

◆ getBoundingBox()

Box lsst::sphgeom::Circle::getBoundingBox ( ) const
overridevirtual

getBoundingBox returns a bounding-box for this region.

Implements lsst::sphgeom::Region.

Definition at line 214 of file Circle.cc.

214 {
215 LonLat c(_center);
216 Angle h = _openingAngle + 2.0 * Angle(MAX_ASIN_ERROR);
217 NormalizedAngle w(Box::halfWidthForCircle(h, c.getLat()) +
219 return Box(c, w, h);
220}
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at...
Definition: Box.cc:43
double w
Definition: CoaddPsf.cc:69

◆ getBoundingBox3d()

Box3d lsst::sphgeom::Circle::getBoundingBox3d ( ) const
overridevirtual

getBoundingBox3d returns a 3-dimensional bounding-box for this region.

Implements lsst::sphgeom::Region.

Definition at line 222 of file Circle.cc.

222 {
223 static double const MAX_BOUNDARY_ERROR = 6.2e-16; // > 5.5ε, where ε = 2^-53
224 if (isEmpty()) {
225 return Box3d();
226 }
227 if (isFull()) {
229 }
230 // Given circle center c and standard basis vector eᵢ, to check whether
231 // ±eᵢ is inside the circle we need to check that (c ∓ eᵢ)·(c ∓ eᵢ) ≤ s.
232 // Since c·c = 1, eᵢ·eᵢ = 1 (c and eᵢ are unit vectors) this is the
233 // same as checking that 2 ∓ 2c·eᵢ ≤ s, or 2 ∓ 2cᵢ ≤ s, where cᵢ is
234 // the i-th component of c.
235 //
236 // Besides any standard basis vectors inside the circle, the bounding box
237 // must also include the circle boundary. To find the extent of this
238 // boundary along a particular axis, note that we can write the i-th
239 // component of the circle center vector as the sine of a latitude angle
240 // (treating the i-th standard basis vector as "north"). So given a circle
241 // opening angle θ, the desired extent is
242 //
243 // [min(sin(asin(cᵢ) ± θ)), max(sin(asin(cᵢ) ± θ))]
244 //
245 // which can be simplified using the usual trigonometric identities to
246 // arrive at the code below.
247 Interval1d e[3];
248 double s = sin(_openingAngle);
249 double c = cos(_openingAngle);
250 for (int i = 0; i < 3; ++i) {
251 double ci = _center(i);
252 double di = std::sqrt(1.0 - ci * ci);
253 double bmin = 1.0, bmax = -1.0;
254 if (2.0 - 2.0 * ci <= _squaredChordLength) {
255 bmax = 1.0;
256 }
257 if (2.0 + 2.0 * ci <= _squaredChordLength) {
258 bmin = -1.0;
259 }
260 double b0 = ci * c + di * s;
261 bmax = std::max(bmax, b0 + MAX_BOUNDARY_ERROR);
262 bmin = std::min(bmin, b0 - MAX_BOUNDARY_ERROR);
263 double b1 = ci * c - di * s;
264 bmax = std::max(bmax, b1 + MAX_BOUNDARY_ERROR);
265 bmin = std::min(bmin, b1 - MAX_BOUNDARY_ERROR);
266 e[i] = Interval1d(std::max(-1.0, bmin), std::min(1.0, bmax));
267 }
268 return Box3d(e[0], e[1], e[2]);
269}
static Box3d aroundUnitSphere()
aroundUnitSphere returns a minimal Box3d containing the unit sphere.
Definition: Box3d.h:56
T sqrt(T... args)

◆ getBoundingCircle()

Circle lsst::sphgeom::Circle::getBoundingCircle ( ) const
inlineoverridevirtual

getBoundingCircle returns a bounding-circle for this region.

Implements lsst::sphgeom::Region.

Definition at line 228 of file Circle.h.

228{ return *this; }

◆ getCenter()

UnitVector3d const & lsst::sphgeom::Circle::getCenter ( ) const
inline

getCenter returns the center of this circle as a unit vector.

It is arbitrary for empty and full circles.

Definition at line 118 of file Circle.h.

118{ return _center; }

◆ getOpeningAngle()

Angle lsst::sphgeom::Circle::getOpeningAngle ( ) const
inline

getOpeningAngle returns the opening angle of this circle - that is, the angle between its center vector and points on its boundary.

It is negative or NaN for empty circles, and at least PI for full circles.

Definition at line 128 of file Circle.h.

128{ return _openingAngle; }

◆ getSquaredChordLength()

double lsst::sphgeom::Circle::getSquaredChordLength ( ) const
inline

getSquaredChordLength returns the squared length of chords between the circle center and points on the circle boundary.

It is negative or NaN for empty circles, and at least 4 for full circles.

Definition at line 123 of file Circle.h.

123{ return _squaredChordLength; }

◆ intersects() [1/2]

bool lsst::sphgeom::Circle::intersects ( Circle const &  x) const
inline

intersects returns true if the intersection of this circle and x is non-empty.

Definition at line 145 of file Circle.h.

145{ return !isDisjointFrom(x); }
bool isDisjointFrom(UnitVector3d const &x) const
Definition: Circle.h:137

◆ intersects() [2/2]

bool lsst::sphgeom::Circle::intersects ( UnitVector3d const &  x) const
inline

intersects returns true if the intersection of this circle and x is non-empty.

Definition at line 144 of file Circle.h.

144{ return contains(x); }

◆ isDisjointFrom() [1/2]

bool lsst::sphgeom::Circle::isDisjointFrom ( Circle const &  x) const

isDisjointFrom returns true if the intersection of this circle and x is empty.

Definition at line 79 of file Circle.cc.

79 {
80 if (isEmpty() || x.isEmpty()) {
81 return true;
82 }
83 if (isFull() || x.isFull()) {
84 return false;
85 }
86 NormalizedAngle cc(_center, x._center);
87 return cc > _openingAngle + x._openingAngle +
88 4.0 * Angle(MAX_ASIN_ERROR);
89}

◆ isDisjointFrom() [2/2]

bool lsst::sphgeom::Circle::isDisjointFrom ( UnitVector3d const &  x) const
inline

isDisjointFrom returns true if the intersection of this circle and x is empty.

Definition at line 137 of file Circle.h.

137{ return !contains(x); }

◆ isEmpty()

bool lsst::sphgeom::Circle::isEmpty ( ) const
inline

Definition at line 109 of file Circle.h.

109 {
110 // Return true when _squaredChordLength is negative or NaN.
111 return !(_squaredChordLength >= 0.0);
112 }

◆ isFull()

bool lsst::sphgeom::Circle::isFull ( ) const
inline

Definition at line 114 of file Circle.h.

114{ return _squaredChordLength >= 4.0; }

◆ isWithin() [1/2]

bool lsst::sphgeom::Circle::isWithin ( Circle const &  x) const
inline

isWithin returns true if the intersection of this circle and x is this circle.

Definition at line 152 of file Circle.h.

152{ return x.contains(*this); }

◆ isWithin() [2/2]

bool lsst::sphgeom::Circle::isWithin ( UnitVector3d const &  ) const
inline

isWithin returns true if the intersection of this circle and x is this circle.

Definition at line 151 of file Circle.h.

151{ return isEmpty(); }

◆ openingAngleFor()

Angle lsst::sphgeom::Circle::openingAngleFor ( double  squaredChordLength)
static

openingAngleFor computes and returns the angular separation between points in S² that are separated by the given squared chord length.

The squared chord length l² and angle θ are related by l² = 4 sin²(θ/2).

Definition at line 52 of file Circle.cc.

52 {
53 // Note: the maximum error in the opening angle (and circle bounding box
54 // width) computations is ~ 2 * MAX_ASIN_ERROR.
55 if (squaredChordLength < 0.0) {
56 return Angle(-1.0);
57 }
58 if (squaredChordLength >= 4.0) {
59 return Angle(PI);
60 }
61 return Angle(2.0 * std::asin(0.5 * std::sqrt(squaredChordLength)));
62}
T asin(T... args)

◆ operator!=()

bool lsst::sphgeom::Circle::operator!= ( Circle const &  c) const
inline

Definition at line 107 of file Circle.h.

107{ return !(*this == c); }

◆ operator==()

bool lsst::sphgeom::Circle::operator== ( Circle const &  c) const
inline

Definition at line 100 of file Circle.h.

100 {
101 return (isEmpty() && c.isEmpty()) ||
102 (isFull() && c.isFull()) ||
103 (_center == c._center &&
104 _squaredChordLength == c._squaredChordLength &&
105 _openingAngle == c._openingAngle);
106 }

◆ relate() [1/6]

Relationship lsst::sphgeom::Circle::relate ( Box const &  ) const
overridevirtual

relate computes the spatial relationships between this region A and another region B. The return value S is a bitset with the following properties:

  • Bit S & DISJOINT is set only if A and B do not have any points in common.
  • Bit S & CONTAINS is set only if A contains all points in B.
  • Bit S & WITHIN is set only if B contains all points in A.

Said another way: if the CONTAINS, WITHIN or DISJOINT bit is set, then the corresponding spatial relationship between the two regions holds conclusively. If it is not set, the relationship may or may not hold.

These semantics allow for conservative relationship computations. In particular, a Region may choose to implement relate by replacing itself and/or the argument with a simplified bounding region.

Implements lsst::sphgeom::Region.

Definition at line 280 of file Circle.cc.

280 {
281 // Box-Circle relations are implemented by Box.
282 return invert(b.relate(*this));
283}
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55

◆ relate() [2/6]

Relationship lsst::sphgeom::Circle::relate ( Circle const &  ) const
overridevirtual

relate computes the spatial relationships between this region A and another region B. The return value S is a bitset with the following properties:

  • Bit S & DISJOINT is set only if A and B do not have any points in common.
  • Bit S & CONTAINS is set only if A contains all points in B.
  • Bit S & WITHIN is set only if B contains all points in A.

Said another way: if the CONTAINS, WITHIN or DISJOINT bit is set, then the corresponding spatial relationship between the two regions holds conclusively. If it is not set, the relationship may or may not hold.

These semantics allow for conservative relationship computations. In particular, a Region may choose to implement relate by replacing itself and/or the argument with a simplified bounding region.

Implements lsst::sphgeom::Region.

Definition at line 285 of file Circle.cc.

285 {
286 if (isEmpty()) {
287 if (c.isEmpty()) {
288 return CONTAINS | DISJOINT | WITHIN;
289 }
290 return DISJOINT | WITHIN;
291 } else if (c.isEmpty()) {
292 return CONTAINS | DISJOINT;
293 }
294 // Neither circle is empty.
295 if (isFull()) {
296 if (c.isFull()) {
297 return CONTAINS | WITHIN;
298 }
299 return CONTAINS;
300 } else if (c.isFull()) {
301 return WITHIN;
302 }
303 // Special case equality, which can be missed by logic below due to
304 // round-off error.
305 if (*this == c) {
306 return CONTAINS | WITHIN;
307 }
308 // Neither circle is full.
309 NormalizedAngle cc(_center, c._center);
310 if (cc > _openingAngle + c._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR)) {
311 return DISJOINT;
312 }
313 if (cc + c._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <= _openingAngle) {
314 return CONTAINS;
315 } else if (cc + _openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <=
316 c._openingAngle) {
317 return WITHIN;
318 }
319 return INTERSECTS;
320}

◆ relate() [3/6]

Relationship lsst::sphgeom::Circle::relate ( ConvexPolygon const &  ) const
overridevirtual

relate computes the spatial relationships between this region A and another region B. The return value S is a bitset with the following properties:

  • Bit S & DISJOINT is set only if A and B do not have any points in common.
  • Bit S & CONTAINS is set only if A contains all points in B.
  • Bit S & WITHIN is set only if B contains all points in A.

Said another way: if the CONTAINS, WITHIN or DISJOINT bit is set, then the corresponding spatial relationship between the two regions holds conclusively. If it is not set, the relationship may or may not hold.

These semantics allow for conservative relationship computations. In particular, a Region may choose to implement relate by replacing itself and/or the argument with a simplified bounding region.

Implements lsst::sphgeom::Region.

Definition at line 322 of file Circle.cc.

322 {
323 // ConvexPolygon-Circle relations are implemented by ConvexPolygon.
324 return invert(p.relate(*this));
325}

◆ relate() [4/6]

Relationship lsst::sphgeom::Circle::relate ( Ellipse const &  ) const
overridevirtual

relate computes the spatial relationships between this region A and another region B. The return value S is a bitset with the following properties:

  • Bit S & DISJOINT is set only if A and B do not have any points in common.
  • Bit S & CONTAINS is set only if A contains all points in B.
  • Bit S & WITHIN is set only if B contains all points in A.

Said another way: if the CONTAINS, WITHIN or DISJOINT bit is set, then the corresponding spatial relationship between the two regions holds conclusively. If it is not set, the relationship may or may not hold.

These semantics allow for conservative relationship computations. In particular, a Region may choose to implement relate by replacing itself and/or the argument with a simplified bounding region.

Implements lsst::sphgeom::Region.

Definition at line 327 of file Circle.cc.

327 {
328 // Ellipse-Circle relations are implemented by Ellipse.
329 return invert(e.relate(*this));
330}

◆ relate() [5/6]

Relationship lsst::sphgeom::Circle::relate ( Region const &  ) const
inlineoverridevirtual

relate computes the spatial relationships between this region A and another region B. The return value S is a bitset with the following properties:

  • Bit S & DISJOINT is set only if A and B do not have any points in common.
  • Bit S & CONTAINS is set only if A contains all points in B.
  • Bit S & WITHIN is set only if B contains all points in A.

Said another way: if the CONTAINS, WITHIN or DISJOINT bit is set, then the corresponding spatial relationship between the two regions holds conclusively. If it is not set, the relationship may or may not hold.

These semantics allow for conservative relationship computations. In particular, a Region may choose to implement relate by replacing itself and/or the argument with a simplified bounding region.

Implements lsst::sphgeom::Region.

Definition at line 237 of file Circle.h.

237 {
238 // Dispatch on the type of r.
239 return invert(r.relate(*this));
240 }

◆ relate() [6/6]

Relationship lsst::sphgeom::Circle::relate ( UnitVector3d const &  v) const

Definition at line 271 of file Circle.cc.

271 {
272 if (contains(v)) {
273 return CONTAINS;
274 } else if (isEmpty()) {
275 return DISJOINT | WITHIN;
276 }
277 return DISJOINT;
278}

◆ squaredChordLengthFor()

double lsst::sphgeom::Circle::squaredChordLengthFor ( Angle  openingAngle)
static

squaredChordLengthFor computes and returns the squared chord length between points in S² that are separated by the given angle.

The squared chord length l² and angle θ are related by l² = 4 sin²(θ/2).

Definition at line 41 of file Circle.cc.

41 {
42 if (a.asRadians() < 0.0) {
43 return -1.0;
44 }
45 if (a.asRadians() >= PI) {
46 return 4.0;
47 }
48 double s = sin(0.5 * a);
49 return 4.0 * s * s;
50}

Member Data Documentation

◆ TYPE_CODE

constexpr uint8_t lsst::sphgeom::Circle::TYPE_CODE = 'c'
staticconstexpr

Definition at line 48 of file Circle.h.


The documentation for this class was generated from the following files: