LSST Applications g063fba187b+cac8b7c890,g0f08755f38+6aee506743,g1653933729+a8ce1bb630,g168dd56ebc+a8ce1bb630,g1a2382251a+b4475c5878,g1dcb35cd9c+8f9bc1652e,g20f6ffc8e0+6aee506743,g217e2c1bcf+73dee94bd0,g28da252d5a+1f19c529b9,g2bbee38e9b+3f2625acfc,g2bc492864f+3f2625acfc,g3156d2b45e+6e55a43351,g32e5bea42b+1bb94961c2,g347aa1857d+3f2625acfc,g35bb328faa+a8ce1bb630,g3a166c0a6a+3f2625acfc,g3e281a1b8c+c5dd892a6c,g3e8969e208+a8ce1bb630,g414038480c+5927e1bc1e,g41af890bb2+8a9e676b2a,g7af13505b9+809c143d88,g80478fca09+6ef8b1810f,g82479be7b0+f568feb641,g858d7b2824+6aee506743,g89c8672015+f4add4ffd5,g9125e01d80+a8ce1bb630,ga5288a1d22+2903d499ea,gb58c049af0+d64f4d3760,gc28159a63d+3f2625acfc,gcab2d0539d+b12535109e,gcf0d15dbbd+46a3f46ba9,gda6a2b7d83+46a3f46ba9,gdaeeff99f8+1711a396fd,ge79ae78c31+3f2625acfc,gef2f8181fd+0a71e47438,gf0baf85859+c1f95f4921,gfa517265be+6aee506743,gfa999e8aa5+17cd334064,w.2024.51
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Public Attributes | Static Protected Member Functions | 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 override
 isEmpty returns true when a region does not contain any points.
 
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
 
TriState overlaps (Region const &other) const override
 
TriState overlaps (Box const &) const override
 
TriState overlaps (Circle const &) const override
 
TriState overlaps (ConvexPolygon const &) const override
 
TriState overlaps (Ellipse const &) const override
 
std::vector< std::uint8_tencode () 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::vector< std::unique_ptr< Region > > getRegions (Region const &region)
 getRegions returns a vector of Region.
 
static std::unique_ptr< Circledecode (std::vector< std::uint8_t > const &s)
 
static std::unique_ptr< Circledecode (std::uint8_t const *buffer, size_t n)
 
static std::unique_ptr< RegiondecodeBase64 (std::string const &s)
 
static std::unique_ptr< RegiondecodeBase64 (std::string_view const &s)
 
static TriState decodeOverlapsBase64 (std::string const &s)
 
static TriState decodeOverlapsBase64 (std::string_view const &s)
 

Static Public Attributes

static constexpr std::uint8_t TYPE_CODE = 'c'
 

Static Protected Member Functions

static TriState _relationship_to_overlaps (Relationship r)
 

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

Constructor & Destructor Documentation

◆ Circle() [1/4]

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

This constructor creates an empty circle.

Definition at line 73 of file Circle.h.

73 :
74 _center(UnitVector3d::Z()),
75 _squaredChordLength(-1.0),
76 _openingAngle(-1.0)
77 {}
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 84 of file Circle.h.

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

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

93 :
94 _center(c),
95 _squaredChordLength(squaredChordLengthFor(a)),
96 _openingAngle(a)
97 {}
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 102 of file Circle.h.

102 :
103 _center(c),
104 _squaredChordLength(cl2),
105 _openingAngle(openingAngleFor(cl2))
106 {}
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

◆ _relationship_to_overlaps()

static TriState lsst::sphgeom::Region::_relationship_to_overlaps ( Relationship r)
inlinestaticprotectedinherited

Definition at line 206 of file Region.h.

206 {
207 // `relate` returns exact relation when specific bit is set, if it is
208 // not then relation may be true or not.
209 if ((r & DISJOINT) == DISJOINT) {
210 return TriState(false);
211 }
212 if ((r & (WITHIN | CONTAINS)).any()) {
213 return TriState(true);
214 }
215 return TriState();
216 }
bool any(CoordinateExpr< N > const &expr) noexcept
Return true if any elements are true.

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

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

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

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

◆ 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
static Circle empty()
Definition Circle.h:58
bool isFull() const
Definition Circle.h:122
bool isEmpty() const override
isEmpty returns true when a region does not contain any points.
Definition Circle.h:117
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 230 of file Circle.h.

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

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

225{ 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 117 of file Region.cc.

54 {
55 return contains(UnitVector3d(LonLat::fromRadians(lon, lat)));
56}
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 113 of file Region.cc.

50 {
51 return contains(UnitVector3d(x, y, z));
52}
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 238 of file Circle.h.

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

◆ decode() [1/2]

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

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

Definition at line 371 of file Circle.cc.

371 {
372 if (buffer == nullptr || n != ENCODED_SIZE || *buffer != TYPE_CODE) {
373 throw std::runtime_error("Byte-string is not an encoded Circle");
374 }
375 std::unique_ptr<Circle> circle(new Circle);
376 ++buffer;
377 double x = decodeDouble(buffer); buffer += 8;
378 double y = decodeDouble(buffer); buffer += 8;
379 double z = decodeDouble(buffer); buffer += 8;
380 double squaredChordLength = decodeDouble(buffer); buffer += 8;
381 double openingAngle = decodeDouble(buffer); buffer += 8;
382 circle->_center = UnitVector3d::fromNormalized(x, y, z);
383 circle->_squaredChordLength = squaredChordLength;
384 circle->_openingAngle = Angle(openingAngle);
385 return circle;
386}
static constexpr std::uint8_t TYPE_CODE
Definition Circle.h:56
static UnitVector3d fromNormalized(Vector3d const &v)
fromNormalized returns the unit vector equal to v, which is assumed to be normalized.
double decodeDouble(std::uint8_t const *buffer)
decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
Definition codec.h:77

◆ decode() [2/2]

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

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

Definition at line 267 of file Circle.h.

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

◆ decodeBase64() [1/2]

static std::unique_ptr< Region > lsst::sphgeom::Region::decodeBase64 ( std::string const & s)
inlinestaticinherited

decodeBase64 deserializes a Region from an ASCII string produced by encode and then base64-encoding that result.

This method also interprets ':' as a delimiter for the elements of a UnionRegion, to support cases where a union of region is constructed server-side in a database as a concatenation with that delimiter.

Definition at line 176 of file Region.h.

176 {
177 return decodeBase64(s);
178 }
static std::unique_ptr< Region > decodeBase64(std::string const &s)
Definition Region.h:176

◆ decodeBase64() [2/2]

std::unique_ptr< Region > lsst::sphgeom::Region::decodeBase64 ( std::string_view const & s)
staticinherited

decodeBase64 deserializes a Region from an ASCII string produced by encode and then base64-encoding that result.

This method also interprets ':' as a delimiter for the elements of a UnionRegion, to support cases where a union of region is constructed server-side in a database as a concatenation with that delimiter.

Definition at line 93 of file Region.cc.

93 {
94 if (s.empty()) {
95 return std::unique_ptr<UnionRegion>(new UnionRegion({}));
96 }
97 auto region_begin = s.begin();
98 auto region_end = std::find(s.begin(), s.end(), ':');
99 if (region_end != s.end()) {
101 while (region_end != s.end()) {
102 auto bytes = base64::decode_into<std::vector<std::uint8_t>>(region_begin, region_end);
103 union_args.push_back(decode(bytes));
104 region_begin = region_end;
105 ++region_begin;
106 region_end = std::find(region_begin, s.end(), ':');
107 }
108 auto bytes = base64::decode_into<std::vector<std::uint8_t>>(region_begin, region_end);
109 union_args.push_back(decode(bytes));
110 return std::unique_ptr<UnionRegion>(new UnionRegion(std::move(union_args)));
111 } else {
112 auto bytes = base64::decode_into<std::vector<std::uint8_t>>(region_begin, region_end);
113 return decode(bytes);
114 }
115}
table::Key< table::Array< std::uint8_t > > bytes
Definition python.h:135
static std::unique_ptr< Region > decode(std::vector< std::uint8_t > const &s)
Definition Region.h:162
T find(T... args)
T move(T... args)
T push_back(T... args)

◆ decodeOverlapsBase64() [1/2]

static TriState lsst::sphgeom::Region::decodeOverlapsBase64 ( std::string const & s)
inlinestaticinherited

decodeOverlapsBase64 evaluates an encoded overlap expression.

A single overlap expression is formed by concatenating a pair of base64-encoded regions (Region::encode then base64 encoding) with '&' as the delimiter. Multiple such pairwise overlap expressions can then be concatenated with '|' as the delimiter to form the logical OR.

Definition at line 190 of file Region.h.

190 {
191 return decodeOverlapsBase64(s);
192 }
static TriState decodeOverlapsBase64(std::string const &s)
Definition Region.h:190

◆ decodeOverlapsBase64() [2/2]

TriState lsst::sphgeom::Region::decodeOverlapsBase64 ( std::string_view const & s)
staticinherited

decodeOverlapsBase64 evaluates an encoded overlap expression.

A single overlap expression is formed by concatenating a pair of base64-encoded regions (Region::encode then base64 encoding) with '&' as the delimiter. Multiple such pairwise overlap expressions can then be concatenated with '|' as the delimiter to form the logical OR.

Definition at line 117 of file Region.cc.

117 {
118 TriState result(false);
119 if (s.empty()) {
120 // False makes the most sense as the limit of a logical OR of zero
121 // terms (e.g. `any([])` in Python).
122 return result;
123 }
124 auto begin = s.begin();
125 while (result != true) { // if result is known to be true, we're done.
126 auto mid = std::find(begin, s.end(), '&');
127 if (mid == s.end()) {
128 throw std::runtime_error("No '&' found in encoded overlap expression term.");
129 }
130 auto a = Region::decode(base64::decode_into<std::vector<std::uint8_t>>(begin, mid));
131 ++mid;
132 auto end = std::find(mid, s.end(), '|');
133 auto b = Region::decode(base64::decode_into<std::vector<std::uint8_t>>(mid, end));
134 result = result | a->overlaps(*b);
135 if (end == s.end()) {
136 break;
137 } else {
138 begin = end;
139 ++begin;
140 }
141 }
142 return result;
143}
py::object result
Definition _schema.cc:429
int end
T begin(T... args)

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

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

◆ empty()

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

Definition at line 58 of file Circle.h.

58{ return Circle(); }

◆ encode()

std::vector< std::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 358 of file Circle.cc.

358 {
361 buffer.reserve(ENCODED_SIZE);
362 buffer.push_back(tc);
363 encodeDouble(_center.x(), buffer);
364 encodeDouble(_center.y(), buffer);
365 encodeDouble(_center.z(), buffer);
366 encodeDouble(_squaredChordLength, buffer);
367 encodeDouble(_openingAngle.asRadians(), buffer);
368 return buffer;
369}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition Angle.h:92
void encodeDouble(double item, std::vector< std::uint8_t > &buffer)
encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.
Definition codec.h:57
T reserve(T... args)

◆ erodeBy()

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

Definition at line 209 of file Circle.h.

209{ 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 210 of file Circle.h.

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

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

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

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

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

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

60{ 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 213 of file Circle.h.

213 {
214 return PI * std::max(0.0, std::min(_squaredChordLength, 4.0));
215 }
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:70

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

236{ 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 126 of file Circle.h.

126{ 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 136 of file Circle.h.

136{ return _openingAngle; }

◆ getRegions()

std::vector< std::unique_ptr< Region > > lsst::sphgeom::Region::getRegions ( Region const & region)
staticinherited

getRegions returns a vector of Region.

Definition at line 145 of file Region.cc.

145 {
147 if (auto union_region = dynamic_cast<UnionRegion const *>(&region)) {
148 for(unsigned i = 0; i < union_region->nOperands(); ++i) {
149 result.emplace_back(union_region->getOperand(i).clone());
150 }
151 } else if(auto intersection_region = dynamic_cast<IntersectionRegion const *>(&region)) {
152 for(unsigned i = 0; i < intersection_region->nOperands(); ++i) {
153 result.emplace_back(intersection_region->getOperand(i).clone());
154 }
155 } else {
156 result.emplace_back(region.clone());
157 }
158 return result;
159}
T emplace_back(T... args)

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

131{ 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 153 of file Circle.h.

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

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

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

145{ return !contains(x); }

◆ isEmpty()

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

isEmpty returns true when a region does not contain any points.

Implements lsst::sphgeom::Region.

Definition at line 117 of file Circle.h.

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

◆ isFull()

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

Definition at line 122 of file Circle.h.

122{ 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 160 of file Circle.h.

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

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

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

◆ operator==()

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

Definition at line 108 of file Circle.h.

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

◆ overlaps() [1/5]

TriState lsst::sphgeom::Circle::overlaps ( Box const & ) const
overridevirtual

overlaps tests whether two regions overlap. This method returns a TriState object, when the value is true it means that regions definitely overlap, false means they are definitely disjont, and unknown state means that they may or may not overlap.

Implements lsst::sphgeom::Region.

Definition at line 339 of file Circle.cc.

339 {
340 // Box-Circle relations are implemented by Box.
341 return b.overlaps(*this);
342}

◆ overlaps() [2/5]

TriState lsst::sphgeom::Circle::overlaps ( Circle const & ) const
overridevirtual

overlaps tests whether two regions overlap. This method returns a TriState object, when the value is true it means that regions definitely overlap, false means they are definitely disjont, and unknown state means that they may or may not overlap.

Implements lsst::sphgeom::Region.

Definition at line 344 of file Circle.cc.

344 {
345 return TriState(not this->isDisjointFrom(c));
346}

◆ overlaps() [3/5]

TriState lsst::sphgeom::Circle::overlaps ( ConvexPolygon const & ) const
overridevirtual

overlaps tests whether two regions overlap. This method returns a TriState object, when the value is true it means that regions definitely overlap, false means they are definitely disjont, and unknown state means that they may or may not overlap.

Implements lsst::sphgeom::Region.

Definition at line 348 of file Circle.cc.

348 {
349 // ConvexPolygon-Circle relations are implemented by ConvexPolygon.
350 return p.overlaps(*this);
351}

◆ overlaps() [4/5]

TriState lsst::sphgeom::Circle::overlaps ( Ellipse const & ) const
overridevirtual

overlaps tests whether two regions overlap. This method returns a TriState object, when the value is true it means that regions definitely overlap, false means they are definitely disjont, and unknown state means that they may or may not overlap.

Implements lsst::sphgeom::Region.

Definition at line 353 of file Circle.cc.

353 {
354 // Ellipse-Circle relations are implemented by Ellipse.
355 return e.overlaps(*this);
356}

◆ overlaps() [5/5]

TriState lsst::sphgeom::Circle::overlaps ( Region const & other) const
inlineoverridevirtual

overlaps tests whether two regions overlap. This method returns a TriState object, when the value is true it means that regions definitely overlap, false means they are definitely disjont, and unknown state means that they may or may not overlap.

Implements lsst::sphgeom::Region.

Definition at line 255 of file Circle.h.

255 {
256 return other.overlaps(*this);
257 }

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

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

◆ 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 std::uint8_t lsst::sphgeom::Circle::TYPE_CODE = 'c'
staticconstexpr

Definition at line 56 of file Circle.h.


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