LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+f5613e8b4f,g1470d8bcf6+190ad2ba91,g14a832a312+311607e4ab,g2079a07aa2+86d27d4dc4,g2305ad1205+a8e3196225,g295015adf3+b67ee847e5,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+a761f810f3,g487adcacf7+17c8fdbcbd,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+65b5bd823e,g5a732f18d5+53520f316c,g64a986408d+f5613e8b4f,g6c1bc301e9+51106c2951,g858d7b2824+f5613e8b4f,g8a8a8dda67+585e252eca,g99cad8db69+6729933424,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+ef4e3a5875,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e9bba80f27,gc120e1dc64+eee469a5e5,gc28159a63d+0e5473021a,gcf0d15dbbd+a761f810f3,gdaeeff99f8+f9a426f77a,ge6526c86ff+d4c1d4bfef,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf1cff7945b+f5613e8b4f,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
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.
 
 Circle (UnitVector3d const &c)
 This constructor creates the circle with center c and squared chord length / opening angle of zero.
 
 Circle (UnitVector3d const &c, Angle a)
 This constructor creates a circle with center c and opening angle a.
 
 Circle (UnitVector3d const &c, double cl2)
 This constructor creates a circle with center c and squared chord length cl2.
 
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.
 
double getSquaredChordLength () const
 getSquaredChordLength returns the squared length of chords between the circle center and points on the circle boundary.
 
Angle getOpeningAngle () const
 getOpeningAngle returns the opening angle of this circle - that is, the angle between its center vector and points on its boundary.
 
bool contains (Circle const &x) const
 contains returns true if the intersection of this circle and x is equal to x.
 
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.
 
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.
 
Circlecomplement ()
 complement sets this circle to the closure of its complement.
 
Circle complemented () const
 complemented returns the closure of the complement of this circle.
 
Relationship relate (UnitVector3d const &v) const
 
std::unique_ptr< Regionclone () const override
 clone returns a deep copy of this region.
 
Box getBoundingBox () const override
 getBoundingBox returns a bounding-box for this region.
 
Box3d getBoundingBox3d () const override
 getBoundingBox3d returns a 3-dimensional bounding-box for this region.
 
Circle getBoundingCircle () const override
 getBoundingCircle returns a bounding-circle for this region.
 
bool contains (UnitVector3d const &v) const override
 contains tests whether the given unit vector is inside this region.
 
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.
 
virtual bool contains (UnitVector3d const &) const=0
 contains tests whether the given unit vector is inside this region.
 
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.
 
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.
 
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.
 
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.
 
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 53 of file Circle.h.

Constructor & Destructor Documentation

◆ Circle() [1/4]

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

This constructor creates an empty circle.

Definition at line 72 of file Circle.h.

72 :
73 _center(UnitVector3d::Z()),
74 _squaredChordLength(-1.0),
75 _openingAngle(-1.0)
76 {}
static UnitVector3d Z()

◆ 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 83 of file Circle.h.

83 :
84 _center(c),
85 _squaredChordLength(0.0),
86 _openingAngle(0.0)
87 {}

◆ 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 92 of file Circle.h.

92 :
93 _center(c),
94 _squaredChordLength(squaredChordLengthFor(a)),
95 _openingAngle(a)
96 {}
static double squaredChordLengthFor(Angle openingAngle)
squaredChordLengthFor computes and returns the squared chord length between points in S² that are sep...
Definition Circle.cc:48

◆ 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 101 of file Circle.h.

101 :
102 _center(c),
103 _squaredChordLength(cl2),
104 _openingAngle(openingAngleFor(cl2))
105 {}
static Angle openingAngleFor(double squaredChordLength)
openingAngleFor computes and returns the angular separation between points in S² that are separated b...
Definition Circle.cc:59

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 176 of file Circle.h.

176 {
177 return Circle(*this).clipTo(x);
178 }
Circle()
This constructor creates an empty circle.
Definition Circle.h:72

◆ 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 172 of file Circle.h.

172 {
173 return Circle(*this).clipTo(x);
174 }

◆ 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 103 of file Circle.cc.

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

◆ 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 98 of file Circle.cc.

98 {
99 *this = contains(x) ? Circle(x) : empty();
100 return *this;
101}
bool contains(Circle const &x) const
contains returns true if the intersection of this circle and x is equal to x.
Definition Circle.cc:71

◆ 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 229 of file Circle.h.

229 {
230 return std::unique_ptr<Circle>(new Circle(*this));
231 }

◆ 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 204 of file Circle.cc.

204 {
205 if (isEmpty()) {
206 // The complement of an empty circle is a full circle.
207 _squaredChordLength = 4.0;
208 _openingAngle = Angle(PI);
209 } else if (isFull()) {
210 // The complement of a full circle is an empty circle.
211 _squaredChordLength = -1.0;
212 _openingAngle = Angle(-1.0);
213 } else {
214 _center = -_center;
215 _squaredChordLength = 4.0 - _squaredChordLength;
216 _openingAngle = Angle(PI) - _openingAngle;
217 }
218 return *this;
219}
constexpr double PI
Definition constants.h:43

◆ complemented()

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

complemented returns the closure of the complement of this circle.

Definition at line 224 of file Circle.h.

224{ 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 71 of file Circle.cc.

71 {
72 if (isFull() || x.isEmpty()) {
73 return true;
74 }
75 if (isEmpty() || x.isFull()) {
76 return false;
77 }
78 if (*this == x) {
79 return true;
80 }
81 NormalizedAngle cc(_center, x._center);
82 return _openingAngle >
83 cc + x._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR);
84}

◆ 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 111 of file Region.cc.

51 {
52 return contains(UnitVector3d(LonLat::fromRadians(lon, lat)));
53}
static LonLat fromRadians(double lon, double lat)
Definition LonLat.h:62

◆ 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 107 of file Region.cc.

47 {
48 return contains(UnitVector3d(x, y, z));
49}
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 237 of file Circle.h.

237 {
238 return isFull() ||
239 (v - _center).getSquaredNorm() <= _squaredChordLength;
240 }

◆ 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 258 of file Circle.h.

258 {
259 return decode(s.data(), s.size());
260 }
static std::unique_ptr< Circle > decode(std::vector< uint8_t > const &s)
Definition Circle.h:258

◆ 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 352 of file Circle.cc.

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

◆ 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 194 of file Circle.cc.

194 {
195 if (!isEmpty() && !isFull() &&
196 (r.asRadians() > 0.0 || r.asRadians() < 0.0)) {
197 Angle o = _openingAngle + r;
198 _squaredChordLength = squaredChordLengthFor(o);
199 _openingAngle = o;
200 }
201 return *this;
202}

◆ dilatedBy()

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

Definition at line 207 of file Circle.h.

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

◆ empty()

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

Definition at line 57 of file Circle.h.

57{ 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 339 of file Circle.cc.

339 {
341 uint8_t tc = TYPE_CODE;
342 buffer.reserve(ENCODED_SIZE);
343 buffer.push_back(tc);
344 encodeDouble(_center.x(), buffer);
345 encodeDouble(_center.y(), buffer);
346 encodeDouble(_center.z(), buffer);
347 encodeDouble(_squaredChordLength, buffer);
348 encodeDouble(_openingAngle.asRadians(), buffer);
349 return buffer;
350}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition Angle.h:92
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:56
T push_back(T... args)
T reserve(T... args)

◆ erodeBy()

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

Definition at line 208 of file Circle.h.

208{ 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:194

◆ erodedBy()

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

Definition at line 209 of file Circle.h.

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

◆ 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 194 of file Circle.h.

194 {
195 return Circle(*this).expandTo(x);
196 }

◆ 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 190 of file Circle.h.

190 {
191 return Circle(*this).expandTo(x);
192 }

◆ expandTo() [1/2]

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

expandTo minimally expands this circle to contain x.

Definition at line 154 of file Circle.cc.

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

◆ expandTo() [2/2]

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

expandTo minimally expands this circle to contain x.

Definition at line 130 of file Circle.cc.

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

◆ full()

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

Definition at line 59 of file Circle.h.

59{ 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 212 of file Circle.h.

212 {
213 return PI * std::max(0.0, std::min(_squaredChordLength, 4.0));
214 }
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 221 of file Circle.cc.

221 {
222 LonLat c(_center);
223 Angle h = _openingAngle + 2.0 * Angle(MAX_ASIN_ERROR);
224 NormalizedAngle w(Box::halfWidthForCircle(h, c.getLat()) +
225 Angle(MAX_ASIN_ERROR));
226 return Box(c, w, h);
227}
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:50
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 229 of file Circle.cc.

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

235{ 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 125 of file Circle.h.

125{ 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 135 of file Circle.h.

135{ 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 130 of file Circle.h.

130{ 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 152 of file Circle.h.

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

◆ 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 151 of file Circle.h.

151{ 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 86 of file Circle.cc.

86 {
87 if (isEmpty() || x.isEmpty()) {
88 return true;
89 }
90 if (isFull() || x.isFull()) {
91 return false;
92 }
93 NormalizedAngle cc(_center, x._center);
94 return cc > _openingAngle + x._openingAngle +
95 4.0 * Angle(MAX_ASIN_ERROR);
96}

◆ 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 144 of file Circle.h.

144{ return !contains(x); }

◆ isEmpty()

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

Definition at line 116 of file Circle.h.

116 {
117 // Return true when _squaredChordLength is negative or NaN.
118 return !(_squaredChordLength >= 0.0);
119 }

◆ isFull()

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

Definition at line 121 of file Circle.h.

121{ 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 159 of file Circle.h.

159{ 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 158 of file Circle.h.

158{ 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 59 of file Circle.cc.

59 {
60 // Note: the maximum error in the opening angle (and circle bounding box
61 // width) computations is ~ 2 * MAX_ASIN_ERROR.
62 if (squaredChordLength < 0.0) {
63 return Angle(-1.0);
64 }
65 if (squaredChordLength >= 4.0) {
66 return Angle(PI);
67 }
68 return Angle(2.0 * std::asin(0.5 * std::sqrt(squaredChordLength)));
69}
T asin(T... args)

◆ operator!=()

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

Definition at line 114 of file Circle.h.

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

◆ operator==()

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

Definition at line 107 of file Circle.h.

107 {
108 return (isEmpty() && c.isEmpty()) ||
109 (isFull() && c.isFull()) ||
110 (_center == c._center &&
111 _squaredChordLength == c._squaredChordLength &&
112 _openingAngle == c._openingAngle);
113 }

◆ 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 287 of file Circle.cc.

287 {
288 // Box-Circle relations are implemented by Box.
289 return invert(b.relate(*this));
290}
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.

◆ 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 292 of file Circle.cc.

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

◆ 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 329 of file Circle.cc.

329 {
330 // ConvexPolygon-Circle relations are implemented by ConvexPolygon.
331 return invert(p.relate(*this));
332}

◆ 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 334 of file Circle.cc.

334 {
335 // Ellipse-Circle relations are implemented by Ellipse.
336 return invert(e.relate(*this));
337}

◆ 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 244 of file Circle.h.

244 {
245 // Dispatch on the type of r.
246 return invert(r.relate(*this));
247 }

◆ relate() [6/6]

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

Definition at line 278 of file Circle.cc.

278 {
279 if (contains(v)) {
280 return CONTAINS;
281 } else if (isEmpty()) {
282 return DISJOINT | WITHIN;
283 }
284 return DISJOINT;
285}

◆ 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 48 of file Circle.cc.

48 {
49 if (a.asRadians() < 0.0) {
50 return -1.0;
51 }
52 if (a.asRadians() >= PI) {
53 return 4.0;
54 }
55 double s = sin(0.5 * a);
56 return 4.0 * s * s;
57}

Member Data Documentation

◆ TYPE_CODE

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

Definition at line 55 of file Circle.h.


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