LSST Applications  21.0.0+04719a4bac,21.0.0-1-ga51b5d4+f5e6047307,21.0.0-11-g2b59f77+a9c1acf22d,21.0.0-11-ga42c5b2+86977b0b17,21.0.0-12-gf4ce030+76814010d2,21.0.0-13-g1721dae+760e7a6536,21.0.0-13-g3a573fe+768d78a30a,21.0.0-15-g5a7caf0+f21cbc5713,21.0.0-16-g0fb55c1+b60e2d390c,21.0.0-19-g4cded4ca+71a93a33c0,21.0.0-2-g103fe59+bb20972958,21.0.0-2-g45278ab+04719a4bac,21.0.0-2-g5242d73+3ad5d60fb1,21.0.0-2-g7f82c8f+8babb168e8,21.0.0-2-g8f08a60+06509c8b61,21.0.0-2-g8faa9b5+616205b9df,21.0.0-2-ga326454+8babb168e8,21.0.0-2-gde069b7+5e4aea9c2f,21.0.0-2-gecfae73+1d3a86e577,21.0.0-2-gfc62afb+3ad5d60fb1,21.0.0-25-g1d57be3cd+e73869a214,21.0.0-3-g357aad2+ed88757d29,21.0.0-3-g4a4ce7f+3ad5d60fb1,21.0.0-3-g4be5c26+3ad5d60fb1,21.0.0-3-g65f322c+e0b24896a3,21.0.0-3-g7d9da8d+616205b9df,21.0.0-3-ge02ed75+a9c1acf22d,21.0.0-4-g591bb35+a9c1acf22d,21.0.0-4-g65b4814+b60e2d390c,21.0.0-4-gccdca77+0de219a2bc,21.0.0-4-ge8a399c+6c55c39e83,21.0.0-5-gd00fb1e+05fce91b99,21.0.0-6-gc675373+3ad5d60fb1,21.0.0-64-g1122c245+4fb2b8f86e,21.0.0-7-g04766d7+cd19d05db2,21.0.0-7-gdf92d54+04719a4bac,21.0.0-8-g5674e7b+d1bd76f71f,master-gac4afde19b+a9c1acf22d,w.2021.13
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...
 
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 93 of file Circle.cc.

93  {
94  if (isEmpty() || x.isFull()) {
95  return *this;
96  }
97  if (isFull() || x.isEmpty()) {
98  *this = x;
99  return *this;
100  }
101  Angle a = _openingAngle;
102  Angle b = x._openingAngle;
103  NormalizedAngle cc(_center, x._center);
104  if (cc > a + b + 4.0 * Angle(MAX_ASIN_ERROR)) {
105  // This circle is disjoint from x.
106  *this = empty();
107  return *this;
108  }
109  // The circles (nearly) intersect, or one contains the other.
110  // For now, take the easy route and just use the smaller of
111  // the two circles as a bound on their intersection.
112  //
113  // TODO(smm): Compute the minimal bounding circle.
114  if (b < a) {
115  *this = x;
116  }
117  return *this;
118 }
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 88 of file Circle.cc.

88  {
89  *this = contains(x) ? Circle(x) : empty();
90  return *this;
91 }
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 194 of file Circle.cc.

194  {
195  if (isEmpty()) {
196  // The complement of an empty circle is a full circle.
197  _squaredChordLength = 4.0;
198  _openingAngle = Angle(PI);
199  } else if (isFull()) {
200  // The complement of a full circle is an empty circle.
201  _squaredChordLength = -1.0;
202  _openingAngle = Angle(-1.0);
203  } else {
204  _center = -_center;
205  _squaredChordLength = 4.0 - _squaredChordLength;
206  _openingAngle = Angle(PI) - _openingAngle;
207  }
208  return *this;
209 }
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/2]

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  NormalizedAngle cc(_center, x._center);
72  return _openingAngle >
73  cc + x._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR);
74 }

◆ contains() [2/2]

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

249  {
250  return decode(s.data(), s.size());
251  }
static std::unique_ptr< Circle > decode(std::vector< uint8_t > const &s)
Definition: Circle.h:249
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 337 of file Circle.cc.

337  {
338  if (buffer == nullptr || n != ENCODED_SIZE || *buffer != TYPE_CODE) {
339  throw std::runtime_error("Byte-string is not an encoded Circle");
340  }
341  std::unique_ptr<Circle> circle(new Circle);
342  ++buffer;
343  double x = decodeDouble(buffer); buffer += 8;
344  double y = decodeDouble(buffer); buffer += 8;
345  double z = decodeDouble(buffer); buffer += 8;
346  double squaredChordLength = decodeDouble(buffer); buffer += 8;
347  double openingAngle = decodeDouble(buffer); buffer += 8;
348  circle->_center = UnitVector3d::fromNormalized(x, y, z);
349  circle->_squaredChordLength = squaredChordLength;
350  circle->_openingAngle = Angle(openingAngle);
351  return circle;
352 }
double z
Definition: Match.cc:44
int y
Definition: SpanSet.cc:49
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)
decode extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
Definition: codec.h:59

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

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

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

324  {
325  std::vector<uint8_t> buffer;
326  uint8_t tc = TYPE_CODE;
327  buffer.reserve(ENCODED_SIZE);
328  buffer.push_back(tc);
329  encodeDouble(_center.x(), buffer);
330  encodeDouble(_center.y(), buffer);
331  encodeDouble(_center.z(), buffer);
332  encodeDouble(_squaredChordLength, buffer);
333  encodeDouble(_openingAngle.asRadians(), buffer);
334  return buffer;
335 }
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)
encode appends an IEEE double in little-endian byte order to the end of buffer.
Definition: codec.h:38
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:184

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

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

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

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

211  {
212  LonLat c(_center);
213  Angle h = _openingAngle + 2.0 * Angle(MAX_ASIN_ERROR);
214  NormalizedAngle w(Box::halfWidthForCircle(h, c.getLat()) +
216  return Box(c, w, h);
217 }
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 219 of file Circle.cc.

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

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

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

277  {
278  // Box-Circle relations are implemented by Box.
279  return invert(b.relate(*this));
280 }
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 282 of file Circle.cc.

282  {
283  if (isEmpty()) {
284  if (c.isEmpty()) {
285  return CONTAINS | DISJOINT | WITHIN;
286  }
287  return DISJOINT | WITHIN;
288  } else if (c.isEmpty()) {
289  return CONTAINS | DISJOINT;
290  }
291  // Neither circle is empty.
292  if (isFull()) {
293  if (c.isFull()) {
294  return CONTAINS | WITHIN;
295  }
296  return CONTAINS;
297  } else if (c.isFull()) {
298  return WITHIN;
299  }
300  // Neither circle is full.
301  NormalizedAngle cc(_center, c._center);
302  if (cc > _openingAngle + c._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR)) {
303  return DISJOINT;
304  }
305  if (cc + c._openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <= _openingAngle) {
306  return CONTAINS;
307  } else if (cc + _openingAngle + 4.0 * Angle(MAX_ASIN_ERROR) <=
308  c._openingAngle) {
309  return WITHIN;
310  }
311  return INTERSECTS;
312 }

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

314  {
315  // ConvexPolygon-Circle relations are implemented by ConvexPolygon.
316  return invert(p.relate(*this));
317 }

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

319  {
320  // Ellipse-Circle relations are implemented by Ellipse.
321  return invert(e.relate(*this));
322 }

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

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

◆ relate() [6/6]

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

Definition at line 268 of file Circle.cc.

268  {
269  if (contains(v)) {
270  return CONTAINS;
271  } else if (isEmpty()) {
272  return DISJOINT | WITHIN;
273  }
274  return DISJOINT;
275 }

◆ 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: