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

Box represents a rectangle in spherical coordinate space that contains its boundary. More...

#include <Box.h>

Inheritance diagram for lsst::sphgeom::Box:
lsst::sphgeom::Region

Public Member Functions

 Box ()
 This constructor creates an empty box. More...
 
 Box (LonLat const &p)
 This constructor creates a box containing a single point. More...
 
 Box (LonLat const &p1, LonLat const &p2)
 This constructor creates a box spanning the longitude interval [p1.getLon(), p2.getLon()] and latitude interval [p1.getLat(), p2.getLat()]. More...
 
 Box (LonLat const &p, Angle w, Angle h)
 This constructor creates a box with center p, half-width (in longitude angle) w and half-height (in latitude angle) h. More...
 
 Box (NormalizedAngleInterval const &lon, AngleInterval const &lat)
 This constructor creates a box spanning the given longitude and latitude intervals. More...
 
bool operator== (Box const &b) const
 Two boxes are equal if they contain the same points. More...
 
bool operator!= (Box const &b) const
 
bool operator== (LonLat const &p) const
 A box is equal to a point p if it contains only p. More...
 
bool operator!= (LonLat const &p) const
 
NormalizedAngleInterval const & getLon () const
 getLon returns the longitude interval of this box. More...
 
AngleInterval const & getLat () const
 getLat returns the latitude interval of this box. More...
 
bool isEmpty () const
 isEmpty returns true if this box does not contain any points. More...
 
bool isFull () const
 isFull returns true if this box contains all points on the unit sphere. More...
 
LonLat getCenter () const
 getCenter returns the center of this box. More...
 
NormalizedAngle getWidth () const
 getWidth returns the width in longitude angle of this box. More...
 
Angle getHeight () const
 getHeight returns the height in latitude angle of this box. More...
 
BoxclipTo (LonLat const &x)
 clipTo shrinks this box until it contains only x. More...
 
BoxclipTo (Box const &x)
 x.clipTo(y) sets x to the smallest box containing the intersection of x and y. More...
 
Box clippedTo (LonLat const &x) const
 clippedTo returns the intersection of this box and x. More...
 
Box clippedTo (Box const &x) const
 clippedTo returns the smallest box containing the intersection of this box and x. More...
 
BoxdilateBy (Angle r)
 dilateBy minimally expands this Box to include all points within angular separation r of its boundary. More...
 
Box dilatedBy (Angle r) const
 
BoxdilateBy (Angle w, Angle h)
 dilateBy morphologically dilates or erodes the longitude interval of this box by w, and the latitude interval of this box by h. More...
 
Box dilatedBy (Angle w, Angle h) const
 
BoxerodeBy (Angle r)
 
BoxerodeBy (Angle w, Angle h)
 
Box erodedBy (Angle r) const
 
Box erodedBy (Angle w, Angle h) const
 
Relationship relate (LonLat const &p) const
 
double getArea () const
 getArea returns the area of this box in steradians. More...
 
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 &b) const override
 
Relationship relate (Circle const &) const override
 
Relationship relate (ConvexPolygon const &) const override
 
Relationship relate (Ellipse const &) const override
 
std::vector< uint8_t > encode () const override
 encode serializes this region into an opaque byte string. More...
 
virtual bool contains (UnitVector3d const &) const=0
 contains tests whether the given unit vector is inside this region. More...
 
bool contains (double x, double y, double z) const
 contains tests whether the unit vector defined by the given (not necessarily normalized) coordinates is inside this region. More...
 
bool contains (double lon, double lat) const
 contains tests whether the unit vector defined by the given longitude and latitude coordinates (in radians) is inside this region. More...
 
bool contains (LonLat const &x) const
 
bool contains (Box const &x) const
 
bool isDisjointFrom (LonLat const &x) const
 
bool isDisjointFrom (Box const &x) const
 
bool intersects (LonLat const &x) const
 
bool intersects (Box const &x) const
 
bool isWithin (LonLat const &x) const
 
bool isWithin (Box const &x) const
 
BoxexpandTo (LonLat const &x)
 
BoxexpandTo (Box const &x)
 
Box expandedTo (LonLat const &x) const
 
Box expandedTo (Box const &x) const
 

Static Public Member Functions

static Box fromDegrees (double lon1, double lat1, double lon2, double lat2)
 
static Box fromRadians (double lon1, double lat1, double lon2, double lat2)
 
static Box empty ()
 
static Box full ()
 
static NormalizedAngle halfWidthForCircle (Angle r, Angle lat)
 halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at the given latitude. More...
 
static NormalizedAngleInterval allLongitudes ()
 allLongitudes returns a normalized angle interval containing all valid longitude angles. More...
 
static AngleInterval allLatitudes ()
 allLatitudes returns an angle interval containing all valid latitude angles. More...
 
static std::unique_ptr< Boxdecode (std::vector< uint8_t > const &s)
 
static std::unique_ptr< Boxdecode (uint8_t const *buffer, size_t n)
 

Static Public Attributes

static constexpr uint8_t TYPE_CODE = 'b'
 

Detailed Description

Box represents a rectangle in spherical coordinate space that contains its boundary.

A box can be empty or full (equal to the entire unit sphere), and may contain just a single point. Besides the usual rectangular regions, a box can also represent polar caps or annuli (i.e. when the box spans all longitudes).

For any instance b of this class, the following properties hold:

Definition at line 54 of file Box.h.

Constructor & Destructor Documentation

◆ Box() [1/5]

lsst::sphgeom::Box::Box ( )
inline

This constructor creates an empty box.

Definition at line 92 of file Box.h.

92{}

◆ Box() [2/5]

lsst::sphgeom::Box::Box ( LonLat const &  p)
inlineexplicit

This constructor creates a box containing a single point.

Definition at line 95 of file Box.h.

95 :
96 _lon(p.getLon()),
97 _lat(p.getLat())
98 {
99 _enforceInvariants();
100 }

◆ Box() [3/5]

lsst::sphgeom::Box::Box ( LonLat const &  p1,
LonLat const &  p2 
)
inline

This constructor creates a box spanning the longitude interval [p1.getLon(), p2.getLon()] and latitude interval [p1.getLat(), p2.getLat()].

Definition at line 105 of file Box.h.

105 :
106 _lon(p1.getLon(), p2.getLon()),
107 _lat(p1.getLat(), p2.getLat())
108 {
109 _enforceInvariants();
110 }

◆ Box() [4/5]

lsst::sphgeom::Box::Box ( LonLat const &  p,
Angle  w,
Angle  h 
)
inline

This constructor creates a box with center p, half-width (in longitude angle) w and half-height (in latitude angle) h.

Definition at line 114 of file Box.h.

114 :
115 _lon(NormalizedAngleInterval(p.getLon()).dilatedBy(w)),
116 _lat(AngleInterval(p.getLat()).dilatedBy(h))
117 {
118 _enforceInvariants();
119 }
double w
Definition: CoaddPsf.cc:69

◆ Box() [5/5]

lsst::sphgeom::Box::Box ( NormalizedAngleInterval const &  lon,
AngleInterval const &  lat 
)
inline

This constructor creates a box spanning the given longitude and latitude intervals.

Definition at line 123 of file Box.h.

123 :
124 _lon(lon),
125 _lat(lat)
126 {
127 _enforceInvariants();
128 }

Member Function Documentation

◆ allLatitudes()

static AngleInterval lsst::sphgeom::Box::allLatitudes ( )
inlinestatic

allLatitudes returns an angle interval containing all valid latitude angles.

Definition at line 87 of file Box.h.

87 {
88 return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
89 }
lsst::geom::Angle Angle
Definition: misc.h:33
constexpr double PI
Definition: constants.h:36

◆ allLongitudes()

static NormalizedAngleInterval lsst::sphgeom::Box::allLongitudes ( )
inlinestatic

allLongitudes returns a normalized angle interval containing all valid longitude angles.

Definition at line 81 of file Box.h.

81 {
83 }
static NormalizedAngleInterval full()

◆ clippedTo() [1/2]

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

clippedTo returns the smallest box containing the intersection of this box and x.

The result is not always unique, and x.clippedTo(y) is not guaranteed to equal y.clippedTo(x).

Definition at line 240 of file Box.h.

240{ return Box(*this).clipTo(x); }
double x
Box()
This constructor creates an empty box.
Definition: Box.h:92

◆ clippedTo() [2/2]

Box lsst::sphgeom::Box::clippedTo ( LonLat const &  x) const
inline

clippedTo returns the intersection of this box and x.

Definition at line 235 of file Box.h.

235{ return Box(*this).clipTo(x); }

◆ clipTo() [1/2]

Box & lsst::sphgeom::Box::clipTo ( Box const &  x)
inline

x.clipTo(y) sets x to the smallest box containing the intersection of x and y.

The result is not always unique, and x.clipTo(y) is not guaranteed to equal y.clipTo(x).

Definition at line 227 of file Box.h.

227 {
228 _lon.clipTo(x.getLon());
229 _lat.clipTo(x.getLat());
230 _enforceInvariants();
231 return *this;
232 }
Interval & clipTo(Scalar x)
Definition: Interval.h:159
NormalizedAngleInterval & clipTo(NormalizedAngle x)
clipTo shrinks this interval until all its points are in x.

◆ clipTo() [2/2]

Box & lsst::sphgeom::Box::clipTo ( LonLat const &  x)
inline

clipTo shrinks this box until it contains only x.

If this box does not contain x, it is emptied.

Definition at line 217 of file Box.h.

217 {
218 _lon.clipTo(x.getLon());
219 _lat.clipTo(x.getLat());
220 _enforceInvariants();
221 return *this;
222 }

◆ clone()

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

clone returns a deep copy of this region.

Implements lsst::sphgeom::Region.

Definition at line 303 of file Box.h.

303 {
304 return std::unique_ptr<Box>(new Box(*this));
305 }

◆ contains() [1/6]

bool lsst::sphgeom::Box::contains ( Box const &  x) const
inline

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

Definition at line 178 of file Box.h.

178 {
179 return _lat.contains(x._lat) && _lon.contains(x._lon);
180 }
bool contains(Scalar x) const
Definition: Interval.h:98

◆ contains() [2/6]

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

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

Definition at line 104 of file Region.cc.

44 {
45 return contains(UnitVector3d(LonLat::fromRadians(lon, lat)));
46}
bool contains(LonLat const &x) const
Definition: Box.h:174
static LonLat fromRadians(double lon, double lat)
Definition: LonLat.h:55

◆ contains() [3/6]

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

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

Definition at line 100 of file Region.cc.

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

◆ contains() [4/6]

bool lsst::sphgeom::Box::contains ( LonLat const &  x) const
inline

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

Definition at line 174 of file Box.h.

174 {
175 return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
176 }

◆ contains() [5/6]

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() [6/6]

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

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

Implements lsst::sphgeom::Region.

Definition at line 311 of file Box.h.

311 {
312 return contains(LonLat(v));
313 }

◆ decode() [1/2]

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

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

Definition at line 340 of file Box.h.

340 {
341 return decode(s.data(), s.size());
342 }
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition: Box.h:340
T data(T... args)
T size(T... args)

◆ decode() [2/2]

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

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

Definition at line 459 of file Box.cc.

459 {
460 if (buffer == nullptr || n != ENCODED_SIZE || *buffer != TYPE_CODE) {
461 throw std::runtime_error("Byte-string is not an encoded Box");
462 }
463 std::unique_ptr<Box> box(new Box);
464 ++buffer;
465 double a = decodeDouble(buffer); buffer += 8;
466 double b = decodeDouble(buffer); buffer += 8;
468 a = decodeDouble(buffer); buffer += 8;
469 b = decodeDouble(buffer); buffer += 8;
470 box->_lat = AngleInterval::fromRadians(a, b);
471 box->_enforceInvariants();
472 return box;
473}
table::Key< int > b
table::Key< int > a
static AngleInterval fromRadians(double x, double y)
Definition: AngleInterval.h:49
static constexpr uint8_t TYPE_CODE
Definition: Box.h:56
static NormalizedAngleInterval fromRadians(double a, double b)
double decodeDouble(uint8_t const *buffer)
decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
Definition: codec.h:66

◆ dilateBy() [1/2]

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

dilateBy minimally expands this Box to include all points within angular separation r of its boundary.

If this box is empty or full, or if r is non-positive, there is no effect.

Definition at line 78 of file Box.cc.

78 {
79 // The basic idea is to compute the union of the bounding boxes for all
80 // circles of opening angle r with centers inside this box.
81 //
82 // The bounding box for a circle of opening angle r with center latitude
83 // |δ| ≤ π/2 - r has height 2r.
84 //
85 // Given fixed r, the width of the bounding box for the circle centered at
86 // latitude δ grows monotonically with |δ| - for justification, see the
87 // derivation in halfWidthForCircle(). The maximum width is therefore
88 // attained when the circle is centered at one of the latitude angle
89 // boundaries of this box. If max(|δ|) ≥ π/2 - r, it is 2π.
90 //
91 // Dilating the longitude interval of this box by the maximum width and
92 // the latitude interval by r gives the desired result.
93 if (isEmpty() || isFull() || r <= Angle(0.0)) {
94 return *this;
95 }
96 Angle maxAbsLatitude = std::max(abs(_lat.getA()), abs(_lat.getB()));
97 NormalizedAngle w = halfWidthForCircle(r, maxAbsLatitude);
98 return dilateBy(w, r);
99}
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
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition: Box.h:155
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition: Box.cc:78
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
Scalar getA() const
getA returns the lower endpoint of this interval.
Definition: Interval.h:76
Scalar getB() const
getB returns the upper endpoint of this interval.
Definition: Interval.h:80
T max(T... args)
Angle abs(Angle const &a)
Definition: Angle.h:106

◆ dilateBy() [2/2]

Box & lsst::sphgeom::Box::dilateBy ( Angle  w,
Angle  h 
)

dilateBy morphologically dilates or erodes the longitude interval of this box by w, and the latitude interval of this box by h.

If w is positive, the longitude interval is dilated by [-w,w]. If w is zero, the corresponding interval is not modified, and if it is negative, the longitude interval is eroded by [w,-w]. The action of h on the latitude interval is analogous.

If this box is empty or full, there is no effect. Furthermore, a box containing the north or south pole is not considered to have a latitude boundary there, so that eroding it will not necessarily remove the pole.

If the desired outcome is the bounding box of points within some angular separation r of this box, then dilateBy(r) must be called, not dilateBy(r, r).

Definition at line 101 of file Box.cc.

101 {
102 if (isEmpty() || isFull()) {
103 return *this;
104 }
105 _lon.dilateBy(w);
106 if (!h.isNan()) {
107 Angle a = (_lat.getA() > Angle(-0.5 * PI)) ? _lat.getA() - h : _lat.getA();
108 Angle b = (_lat.getB() < Angle(0.5 * PI)) ? _lat.getB() + h : _lat.getB();
109 _lat = AngleInterval(a, b);
110 }
111 _enforceInvariants();
112 return *this;
113}
NormalizedAngleInterval & dilateBy(Angle x)

◆ dilatedBy() [1/2]

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

Definition at line 273 of file Box.h.

273{ return Box(*this).dilateBy(r); }

◆ dilatedBy() [2/2]

Box lsst::sphgeom::Box::dilatedBy ( Angle  w,
Angle  h 
) const
inline

Definition at line 291 of file Box.h.

291{ return Box(*this).dilateBy(w, h); }

◆ empty()

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

Definition at line 69 of file Box.h.

69{ return Box(); }

◆ encode()

std::vector< uint8_t > lsst::sphgeom::Box::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 447 of file Box.cc.

447 {
449 uint8_t tc = TYPE_CODE;
450 buffer.reserve(ENCODED_SIZE);
451 buffer.push_back(tc);
452 encodeDouble(_lon.getA().asRadians(), buffer);
453 encodeDouble(_lon.getB().asRadians(), buffer);
454 encodeDouble(_lat.getA().asRadians(), buffer);
455 encodeDouble(_lat.getB().asRadians(), buffer);
456 return buffer;
457}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition: Angle.h:85
double asRadians() const
asRadians returns the value of this angle in units of radians.
NormalizedAngle getA() const
getA returns the first endpoint of this interval.
NormalizedAngle getB() const
getB returns the second endpoint of this interval.
void encodeDouble(double item, std::vector< uint8_t > &buffer)
encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.
Definition: codec.h:46
T push_back(T... args)
T reserve(T... args)

◆ erodeBy() [1/2]

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

Definition at line 292 of file Box.h.

292{ return dilateBy(-r); }

◆ erodeBy() [2/2]

Box & lsst::sphgeom::Box::erodeBy ( Angle  w,
Angle  h 
)
inline

Definition at line 293 of file Box.h.

293{ return dilateBy(-w, -h); }

◆ erodedBy() [1/2]

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

Definition at line 294 of file Box.h.

294{ return dilatedBy(-r); }
Box dilatedBy(Angle r) const
Definition: Box.h:273

◆ erodedBy() [2/2]

Box lsst::sphgeom::Box::erodedBy ( Angle  w,
Angle  h 
) const
inline

Definition at line 295 of file Box.h.

295{ return dilatedBy(-w, -h); }

◆ expandedTo() [1/2]

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

expandedTo returns the smallest box containing the union of this box and x. The result is not always unique, and x.expandedTo(y) is not guaranteed to equal y.expandedTo(x).

Definition at line 264 of file Box.h.

264{ return Box(*this).expandTo(x); }

◆ expandedTo() [2/2]

Box lsst::sphgeom::Box::expandedTo ( LonLat const &  x) const
inline

expandedTo returns the smallest box containing the union of this box and x. The result is not always unique, and x.expandedTo(y) is not guaranteed to equal y.expandedTo(x).

Definition at line 263 of file Box.h.

263{ return Box(*this).expandTo(x); }

◆ expandTo() [1/2]

Box & lsst::sphgeom::Box::expandTo ( Box const &  x)
inline

expandTo minimally expands this box to contain x. The result is not always unique, and x.expandTo(y) is not guaranteed to equal y.expandTo(x).

Definition at line 252 of file Box.h.

252 {
253 _lon.expandTo(x.getLon());
254 _lat.expandTo(x.getLat());
255 return *this;
256 }
Interval & expandTo(Scalar x)
Definition: Interval.h:192
NormalizedAngleInterval & expandTo(NormalizedAngle x)

◆ expandTo() [2/2]

Box & lsst::sphgeom::Box::expandTo ( LonLat const &  x)
inline

expandTo minimally expands this box to contain x. The result is not always unique, and x.expandTo(y) is not guaranteed to equal y.expandTo(x).

Definition at line 246 of file Box.h.

246 {
247 _lon.expandTo(x.getLon());
248 _lat.expandTo(x.getLat());
249 return *this;
250 }

◆ fromDegrees()

static Box lsst::sphgeom::Box::fromDegrees ( double  lon1,
double  lat1,
double  lon2,
double  lat2 
)
inlinestatic

Definition at line 59 of file Box.h.

59 {
61 AngleInterval::fromDegrees(lat1, lat2));
62 }
static AngleInterval fromDegrees(double x, double y)
Definition: AngleInterval.h:44
static NormalizedAngleInterval fromDegrees(double a, double b)

◆ fromRadians()

static Box lsst::sphgeom::Box::fromRadians ( double  lon1,
double  lat1,
double  lon2,
double  lat2 
)
inlinestatic

Definition at line 64 of file Box.h.

64 {
66 AngleInterval::fromRadians(lat1, lat2));
67 }

◆ full()

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

Definition at line 71 of file Box.h.

71{ return Box(allLongitudes(), allLatitudes()); }
static NormalizedAngleInterval allLongitudes()
allLongitudes returns a normalized angle interval containing all valid longitude angles.
Definition: Box.h:81
static AngleInterval allLatitudes()
allLatitudes returns an angle interval containing all valid latitude angles.
Definition: Box.h:87

◆ getArea()

double lsst::sphgeom::Box::getArea ( ) const

getArea returns the area of this box in steradians.

Definition at line 115 of file Box.cc.

115 {
116 if (isEmpty()) {
117 return 0.0;
118 }
119 // Given a, b ∈ [-π/2, π/2] and a std::sin implementation that is not
120 // correctly rounded, b > a does not imply that std::sin(b) > std::sin(a).
121 // To avoid potentially returning a negative area, defensively take an
122 // absolute value.
123 double dz = sin(_lat.getB()) - sin(_lat.getA());
124 return std::fabs(_lon.getSize().asRadians() * dz);
125}
NormalizedAngle getSize() const
getSize returns the size (length, width) of this interval.
T fabs(T... args)
double sin(Angle const &a)
Definition: Angle.h:102

◆ getBoundingBox()

Box lsst::sphgeom::Box::getBoundingBox ( ) const
inlineoverridevirtual

getBoundingBox returns a bounding-box for this region.

Implements lsst::sphgeom::Region.

Definition at line 307 of file Box.h.

307{ return *this; }

◆ getBoundingBox3d()

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

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

Implements lsst::sphgeom::Region.

Definition at line 127 of file Box.cc.

127 {
128 if (isEmpty()) {
129 return Box3d();
130 }
131 if (isFull()) {
133 }
134 double slata = sin(_lat.getA()), clata = cos(_lat.getA());
135 double slatb = sin(_lat.getB()), clatb = cos(_lat.getB());
136 double slona = sin(_lon.getA()), clona = cos(_lon.getA());
137 double slonb = sin(_lon.getB()), clonb = cos(_lon.getB());
138 // Compute the minimum/maximum x/y values of the box vertices.
139 double xmin = std::min(std::min(clona * clata, clonb * clata),
140 std::min(clona * clatb, clonb * clatb)) - 2.5 * EPSILON;
141 double xmax = std::max(std::max(clona * clata, clonb * clata),
142 std::max(clona * clatb, clonb * clatb)) + 2.5 * EPSILON;
143 double ymin = std::min(std::min(slona * clata, slonb * clata),
144 std::min(slona * clatb, slonb * clatb)) - 2.5 * EPSILON;
145 double ymax = std::max(std::max(slona * clata, slonb * clata),
146 std::max(slona * clatb, slonb * clatb)) + 2.5 * EPSILON;
147 // Compute the maximum latitude cosine of points in the box.
148 double mlc;
149 if (_lat.contains(Angle(0.0))) {
150 mlc = 1.0;
151 // The box intersects the equator - the x or y extrema of the box may be
152 // at the intersection of the box edge meridians with the equator.
153 xmin = std::min(xmin, std::min(clona, clonb) - EPSILON);
154 xmax = std::max(xmax, std::max(clona, clonb) + EPSILON);
155 ymin = std::min(ymin, std::min(slona, slonb) - EPSILON);
156 ymax = std::max(ymax, std::max(slona, slonb) + EPSILON);
157 } else {
158 // Note that clata and clatb are positive.
159 mlc = std::max(clata, clatb) + EPSILON;
160 }
161 // Check for extrema on the box edges parallel to the equator.
162 if (_lon.contains(NormalizedAngle(0.0))) {
163 xmax = std::max(xmax, mlc);
164 }
165 if (_lon.contains(NormalizedAngle(0.5 * PI))) {
166 ymax = std::max(ymax, mlc);
167 }
168 if (_lon.contains(NormalizedAngle(PI))) {
169 xmin = std::min(xmin, -mlc);
170 }
171 if (_lon.contains(NormalizedAngle(1.5 * PI))) {
172 ymin = std::min(ymin, -mlc);
173 }
174 // Clamp x/y extrema to [-1, 1]
175 xmin = std::max(-1.0, xmin);
176 xmax = std::min(1.0, xmax);
177 ymin = std::max(-1.0, ymin);
178 ymax = std::min(1.0, ymax);
179 // Compute z extrema.
180 double zmin = std::max(-1.0, slata - EPSILON);
181 double zmax = std::min(1.0, slatb + EPSILON);
182 return Box3d(Interval1d(xmin, xmax),
183 Interval1d(ymin, ymax),
184 Interval1d(zmin, zmax));
185}
int xmax
Definition: SpanSet.cc:48
int xmin
Definition: SpanSet.cc:48
static Box3d aroundUnitSphere()
aroundUnitSphere returns a minimal Box3d containing the unit sphere.
Definition: Box3d.h:56
T min(T... args)
constexpr double EPSILON
Definition: constants.h:54
double cos(Angle const &a)
Definition: Angle.h:103

◆ getBoundingCircle()

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

getBoundingCircle returns a bounding-circle for this region.

Implements lsst::sphgeom::Region.

Definition at line 187 of file Box.cc.

187 {
188 if (isEmpty()) {
189 return Circle::empty();
190 }
191 if (isFull()) {
192 return Circle::full();
193 }
194 NormalizedAngle w = getWidth();
195 // The minimal bounding circle center p lies on the meridian bisecting
196 // this box. Let δ₁ and δ₂ be the minimum and maximum box latitudes.
197 if (w.asRadians() <= PI) {
198 UnitVector3d p;
199 UnitVector3d boxVerts[4] = {
200 UnitVector3d(_lon.getA(), _lat.getA()),
201 UnitVector3d(_lon.getA(), _lat.getB()),
202 UnitVector3d(_lon.getB(), _lat.getA()),
203 UnitVector3d(_lon.getB(), _lat.getB())
204 };
205 // We take advantage of rotational symmetry to fix the bisecting
206 // meridian at a longitude of zero. The box vertices then have
207 // coordinates (±w/2, δ₁), (±w/2, δ₂), and p = (0, ϕ). Converting
208 // to Cartesian coordinates gives p = (cos ϕ, 0, sin ϕ), and box
209 // vertices at (cos w/2 cos δ₁, ±sin w/2 cos δ₁, sin δ₁) and
210 // (cos w/2 cos δ₂, ±sin w/2 cos δ₂, sin δ₂).
211 //
212 // The point p₁ on the meridian that has minimum angular separation
213 // to the vertices with latitude δ₁ lies on the plane they define.
214 // The sum of the two vertex vectors is on that plane and on the plane
215 // containing the meridian. Normalizing to obtain p₁, we have
216 //
217 // (cos ϕ₁, 0, sin ϕ₁) =
218 // λ ((cos w/2 cos δ₁, sin w/2 cos δ₁, sin δ₁) +
219 // (cos w/2 cos δ₁, -sin w/2 cos δ₁, sin δ₁))
220 //
221 // for some scaling factor λ. Simplifying, we get:
222 //
223 // cos ϕ₁ = λ cos w/2 cos δ₁
224 // sin ϕ₁ = λ sin δ₁
225 //
226 // so that
227 //
228 // tan ϕ₁ = sec w/2 tan δ₁
229 //
230 // Similarly, the point p₂ on the meridian that has minimum angular
231 // separation to the vertices with latitude δ₂ satisfies:
232 //
233 // tan ϕ₂ = sec w/2 tan δ₂
234 //
235 // where ϕ₁ ≤ ϕ₂ (since δ₁ ≤ δ₂). Finally, consider the point p₃
236 // separated from each box vertex by the same angle. The dot
237 // products of p₃ with the box vertices are all identical, so
238 //
239 // cos ϕ₃ cos w/2 cos δ₁ + sin ϕ₃ sin δ₁ =
240 // cos ϕ₃ cos w/2 cos δ₂ + sin ϕ₃ sin δ₂
241 //
242 // Rearranging gives:
243 //
244 // tan ϕ₃ = - cos w/2 (cos δ₁ - cos δ₂)/(sin δ₁ - sin δ₂)
245 //
246 // which can be simplified further using a tangent half-angle identity,
247 // yielding:
248 //
249 // tan ϕ₃ = cos w/2 tan (δ₁ + δ₂)/2
250 //
251 // Consider now the function f₁(ϕ) that gives the angular separation
252 // between p with latitude ϕ and the vertices at latitude δ₁. It has
253 // a line of symmetry at ϕ = ϕ₁, and increases monotonically with
254 // |ϕ - ϕ₁|. Similarly, f₂(ϕ) has a minimum at ϕ₂ and increases
255 // monotonically with |ϕ - ϕ₂|. The two functions cross at ϕ₃. The
256 // opening angle of the bounding circle centered at latitude ϕ is
257 // given by g = max(f₁, f₂), which we seek to minimize.
258 //
259 // If ϕ₁ ≤ ϕ₃ ≤ ϕ₂, then g is minimized at ϕ = ϕ₃. Otherwise, it
260 // is minimized at either ϕ₁ or ϕ₂.
261 double phi1, phi2, phi3;
262 double c = cos(0.5 * w);
263 if (c == 0.0) {
264 // This code should never execute. If it does, the implementation
265 // of std::cos is broken.
266 phi1 = ::copysign(0.5 * PI, _lat.getA().asRadians());
267 phi2 = ::copysign(0.5 * PI, _lat.getB().asRadians());
268 phi3 = 0.0;
269 } else {
270 phi1 = std::atan(tan(_lat.getA()) / c);
271 phi2 = std::atan(tan(_lat.getB()) / c);
272 phi3 = std::atan(c * tan(_lat.getCenter()));
273 }
274 if (phi1 <= phi3 && phi3 <= phi2) {
275 p = UnitVector3d(_lon.getCenter(), Angle(phi3));
276 } else {
277 UnitVector3d p1 = UnitVector3d(_lon.getCenter(), Angle(phi1));
278 UnitVector3d p2 = UnitVector3d(_lon.getCenter(), Angle(phi2));
279 if (p1.dot(boxVerts[0]) > p2.dot(boxVerts[1])) {
280 p = p2;
281 } else {
282 p = p1;
283 }
284 }
285 // Compute the maximum squared chord length between p and the box
286 // vertices, so that each one is guaranteed to lie in the bounding
287 // circle, regardless of numerical error in the above.
288 double cl2 = (p - boxVerts[0]).getSquaredNorm();
289 for (int i = 1; i < 4; ++i) {
290 cl2 = std::max(cl2, (p - boxVerts[i]).getSquaredNorm());
291 }
292 // Add double the maximum squared-chord-length error, so that the
293 // bounding circle we return also reliably CONTAINS this box.
294 return Circle(p, cl2 + 2.0 * MAX_SQUARED_CHORD_LENGTH_ERROR);
295 }
296 // The box spans more than π radians in longitude. First, pick the smaller
297 // of the bounding circles centered at the north and south pole.
298 Angle r;
299 UnitVector3d v;
300 if (abs(_lat.getA()) <= abs(_lat.getB())) {
301 v = UnitVector3d::Z();
302 r = Angle(0.5 * PI) - _lat.getA();
303 } else {
304 v = -UnitVector3d::Z();
305 r = _lat.getB() + Angle(0.5 * PI);
306 }
307 // If the box does not span all longitude angles, we also consider the
308 // equatorial bounding circle with center longitude equal to the longitude
309 // of the box center. The smaller of the polar and equatorial bounding
310 // circles is returned.
311 if (!_lon.isFull() && 0.5 * w < r) {
312 r = 0.5 * w;
313 v = UnitVector3d(_lon.getCenter(), Angle(0.0));
314 }
315 return Circle(v, r + 4.0 * Angle(MAX_ASIN_ERROR));
316}
T atan(T... args)
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition: Box.h:165
static Circle empty()
Definition: Circle.h:50
static Circle full()
Definition: Circle.h:52
Scalar getCenter() const
getCenter returns the center of this interval.
Definition: Interval.h:89
bool isFull() const
isFull returns true if this interval contains all normalized angles.
NormalizedAngle getCenter() const
getCenter returns the center of this interval.
static UnitVector3d Z()
Definition: UnitVector3d.h:101
constexpr double MAX_ASIN_ERROR
Definition: constants.h:45
constexpr double MAX_SQUARED_CHORD_LENGTH_ERROR
Definition: constants.h:50
double tan(Angle const &a)
Definition: Angle.h:104

◆ getCenter()

LonLat lsst::sphgeom::Box::getCenter ( ) const
inline

getCenter returns the center of this box.

It is NaN for empty boxes and arbitrary for full boxes.

Definition at line 159 of file Box.h.

159 {
160 return LonLat(_lon.getCenter(), _lat.getCenter());
161 }

◆ getHeight()

Angle lsst::sphgeom::Box::getHeight ( ) const
inline

getHeight returns the height in latitude angle of this box.

It is negative or NaN for empty boxes.

Definition at line 169 of file Box.h.

169{ return _lat.getSize(); }
Scalar getSize() const
getSize returns the size (length, width) of this interval.
Definition: Interval.h:93

◆ getLat()

AngleInterval const & lsst::sphgeom::Box::getLat ( ) const
inline

getLat returns the latitude interval of this box.

Definition at line 148 of file Box.h.

148{ return _lat; }

◆ getLon()

NormalizedAngleInterval const & lsst::sphgeom::Box::getLon ( ) const
inline

getLon returns the longitude interval of this box.

Definition at line 145 of file Box.h.

145{ return _lon; }

◆ getWidth()

NormalizedAngle lsst::sphgeom::Box::getWidth ( ) const
inline

getWidth returns the width in longitude angle of this box.

It is NaN for empty boxes.

Definition at line 165 of file Box.h.

165{ return _lon.getSize(); }

◆ halfWidthForCircle()

NormalizedAngle lsst::sphgeom::Box::halfWidthForCircle ( Angle  r,
Angle  lat 
)
static

halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at the given latitude.

If r is non-positive, the result is zero, and if |lat| + r >= PI/2, the result is PI.

Definition at line 43 of file Box.cc.

43 {
44 if (r <= Angle(0.0)) {
45 return NormalizedAngle(0.0);
46 }
47 // If a circle centered at the given latitude contains a pole, then
48 // its bounding box contains all possible longitudes.
49 if (abs(lat) + r >= Angle(0.5 * PI)) {
50 return NormalizedAngle(PI);
51 }
52 // Now, consider the circle with opening angle r > 0 centered at (0,δ)
53 // with r < π/2 and |δ| ≠ π/2. The circle center vector in ℝ³ is
54 // c = (cos δ, 0, sin δ). Its bounding box spans longitudes [-α,α], where
55 // α is the desired half-width. The plane corresponding to longitude α has
56 // normal vector (-sin α, cos α, 0) and is tangent to the circle at point
57 // p. The great circle segment between the center of the circle and the
58 // plane normal passes through p and has arc length π/2 + r, so that
59 //
60 // (cos δ, 0, sin δ) · (-sin α, cos α, 0) = cos (π/2 + r)
61 //
62 // Solving for α gives
63 //
64 // α = arcsin (sin r / cos δ)
65 //
66 // In the actual computation, there is an absolute value and an explicit
67 // arcsin domain check to cope with rounding errors. An alternate way to
68 // compute this is:
69 //
70 // α = arctan (sin r / √(cos(δ - r) cos(δ + r)))
71 double s = std::fabs(sin(r) / cos(lat));
72 if (s >= 1.0) {
73 return NormalizedAngle(0.5 * PI);
74 }
75 return NormalizedAngle(std::asin(s));
76}
T asin(T... args)

◆ intersects() [1/2]

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

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

Definition at line 198 of file Box.h.

198 {
199 return _lat.intersects(x._lat) && _lon.intersects(x._lon);
200 }
bool intersects(Scalar x) const
Definition: Interval.h:130

◆ intersects() [2/2]

bool lsst::sphgeom::Box::intersects ( LonLat const &  x) const
inline

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

Definition at line 194 of file Box.h.

194 {
195 return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
196 }

◆ isDisjointFrom() [1/2]

bool lsst::sphgeom::Box::isDisjointFrom ( Box const &  x) const
inline

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

Definition at line 188 of file Box.h.

188{ return !intersects(x); }
bool intersects(LonLat const &x) const
Definition: Box.h:194

◆ isDisjointFrom() [2/2]

bool lsst::sphgeom::Box::isDisjointFrom ( LonLat const &  x) const
inline

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

Definition at line 186 of file Box.h.

186{ return !intersects(x); }

◆ isEmpty()

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

isEmpty returns true if this box does not contain any points.

Definition at line 151 of file Box.h.

151{ return _lat.isEmpty(); }
bool isEmpty() const
isEmpty returns true if this interval does not contain any points.
Definition: Interval.h:83

◆ isFull()

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

isFull returns true if this box contains all points on the unit sphere.

Definition at line 155 of file Box.h.

155{ return _lon.isFull() && _lat == allLatitudes(); }

◆ isWithin() [1/2]

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

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

Definition at line 210 of file Box.h.

210 {
211 return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
212 }
bool isWithin(Scalar x) const
Definition: Interval.h:140

◆ isWithin() [2/2]

bool lsst::sphgeom::Box::isWithin ( LonLat const &  x) const
inline

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

Definition at line 206 of file Box.h.

206 {
207 return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
208 }

◆ operator!=() [1/2]

bool lsst::sphgeom::Box::operator!= ( Box const &  b) const
inline

Definition at line 135 of file Box.h.

135{ return !(*this == b); }

◆ operator!=() [2/2]

bool lsst::sphgeom::Box::operator!= ( LonLat const &  p) const
inline

Definition at line 142 of file Box.h.

142{ return !(*this == p); }

◆ operator==() [1/2]

bool lsst::sphgeom::Box::operator== ( Box const &  b) const
inline

Two boxes are equal if they contain the same points.

Definition at line 131 of file Box.h.

131 {
132 return _lon == b._lon && _lat == b._lat;
133 }

◆ operator==() [2/2]

bool lsst::sphgeom::Box::operator== ( LonLat const &  p) const
inline

A box is equal to a point p if it contains only p.

Definition at line 138 of file Box.h.

138 {
139 return _lat == p.getLat() && _lon == p.getLon();
140 }

◆ relate() [1/6]

Relationship lsst::sphgeom::Box::relate ( Box 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 322 of file Box.h.

322 {
323 Relationship r1 = _lon.relate(b._lon);
324 Relationship r2 = _lat.relate(b._lat);
325 // If the box longitude or latitude intervals are disjoint, then the
326 // boxes are disjoint. The other spatial relationships must hold for
327 // both the longitude and latitude intervals in order to hold for the
328 // boxes.
329 return ((r1 & r2) & (CONTAINS | WITHIN)) | ((r1 | r2) & DISJOINT);
330 }
Relationship relate(Scalar x) const
Definition: Interval.h:249
Relationship relate(NormalizedAngle x) const
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition: Relationship.h:35

◆ relate() [2/6]

Relationship lsst::sphgeom::Box::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 318 of file Box.cc.

318 {
319 if (isEmpty()) {
320 if (c.isEmpty()) {
321 return CONTAINS | DISJOINT | WITHIN;
322 }
323 return DISJOINT | WITHIN;
324 } else if (c.isEmpty()) {
325 return CONTAINS | DISJOINT;
326 }
327 if (isFull()) {
328 if (c.isFull()) {
329 return CONTAINS | WITHIN;
330 }
331 return CONTAINS;
332 } else if (c.isFull()) {
333 return WITHIN;
334 }
335 // Neither region is empty or full. We now determine whether or not the
336 // circle and box boundaries intersect.
337 //
338 // If the box vertices are not all inside or all outside of c, then the
339 // boundaries cross.
340 LonLat vertLonLat[4] = {
341 LonLat(_lon.getA(), _lat.getA()),
342 LonLat(_lon.getA(), _lat.getB()),
343 LonLat(_lon.getB(), _lat.getA()),
344 LonLat(_lon.getB(), _lat.getB())
345 };
346 UnitVector3d verts[4];
347 bool inside = false;
348 for (int i = 0; i < 4; ++i) {
349 verts[i] = UnitVector3d(vertLonLat[i]);
350 double d = (verts[i] - c.getCenter()).getSquaredNorm();
351 if (std::fabs(d - c.getSquaredChordLength()) <
353 // A box vertex is close to the circle boundary.
354 return INTERSECTS;
355 }
356 bool b = d < c.getSquaredChordLength();
357 if (i == 0) {
358 inside = b;
359 } else if (inside != b) {
360 // There are box vertices both inside and outside of c.
361 return INTERSECTS;
362 }
363 }
364 UnitVector3d norms[2] = {
367 };
368 if (inside) {
369 // All box vertices are inside c. Look for points in the box edge
370 // interiors that are outside c.
371 for (int i = 0; i < 2; ++i) {
372 double d = getMaxSquaredChordLength(
373 c.getCenter(), verts[2 * i + 1], verts[2 * i], norms[i]);
374 if (d > c.getSquaredChordLength() -
376 return INTERSECTS;
377 }
378 }
379 LonLat cc(-c.getCenter());
380 if (_lon.contains(cc.getLon())) {
381 // The points furthest from the center of c on the small circles
382 // defined by the box edges with constant latitude are in the box
383 // edge interiors. Find the largest squared chord length to either.
384 Angle a = std::min(getMinAngleToCircle(cc.getLat(), _lat.getA()),
385 getMinAngleToCircle(cc.getLat(), _lat.getB()));
387 if (d > c.getSquaredChordLength() -
389 return INTERSECTS;
390 }
391 }
392 // The box boundary is completely inside c. However, the box is not
393 // necessarily within c: consider a circle with opening angle equal to
394 // π - ε. If a box contains the complement of such a circle, then
395 // intersecting it with that circle will punch a hole in the box. In
396 // this case each region contains the boundary of the other, but
397 // neither region contains the other.
398 //
399 // To handle this case, check that the box does not contain the
400 // complement of c - since the boundaries do not intersect, this is the
401 // case iff the box contains the center of the complement of c.
402 if (contains(cc)) {
403 return INTERSECTS;
404 }
405 return WITHIN;
406 }
407 // All box vertices are outside c. Look for points in the box edge
408 // interiors that are inside c.
409 for (int i = 0; i < 2; ++i) {
410 double d = getMinSquaredChordLength(
411 c.getCenter(), verts[2 * i + 1], verts[2 * i], norms[i]);
412 if (d < c.getSquaredChordLength() + MAX_SQUARED_CHORD_LENGTH_ERROR) {
413 return INTERSECTS;
414 }
415 }
416 LonLat cc(c.getCenter());
417 if (_lon.contains(cc.getLon())) {
418 // The points closest to the center of c on the small circles
419 // defined by the box edges with constant latitude are in the box
420 // edge interiors. Find the smallest squared chord length to either.
421 Angle a = std::min(getMinAngleToCircle(cc.getLat(), _lat.getA()),
422 getMinAngleToCircle(cc.getLat(), _lat.getB()));
424 if (d < c.getSquaredChordLength() + MAX_SQUARED_CHORD_LENGTH_ERROR) {
425 return INTERSECTS;
426 }
427 }
428 // The box boundary is completely outside of c. If the box contains the
429 // circle center, then the box contains c. Otherwise, the box and circle
430 // are disjoint.
431 if (contains(cc)) {
432 return CONTAINS;
433 }
434 return DISJOINT;
435}
static double squaredChordLengthFor(Angle openingAngle)
squaredChordLengthFor computes and returns the squared chord length between points in S² that are sep...
Definition: Circle.cc:41
static UnitVector3d orthogonalTo(Vector3d const &v)
orthogonalTo returns an arbitrary unit vector that is orthogonal to v.
Definition: UnitVector3d.cc:34
Angle getMinAngleToCircle(Angle x, Angle c)
getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the poin...
Definition: utils.h:62
double getMaxSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the...
Definition: utils.cc:58
double getMinSquaredChordLength(Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cr...
Definition: utils.cc:36

◆ relate() [3/6]

Relationship lsst::sphgeom::Box::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 437 of file Box.cc.

437 {
438 // ConvexPolygon-Box relations are implemented by ConvexPolygon.
439 return invert(p.relate(*this));
440}
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55

◆ relate() [4/6]

Relationship lsst::sphgeom::Box::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 442 of file Box.cc.

442 {
443 // Ellipse-Box relations are implemented by Ellipse.
444 return invert(e.relate(*this));
445}

◆ relate() [5/6]

Relationship lsst::sphgeom::Box::relate ( LonLat const &  p) const
inline

Definition at line 297 of file Box.h.

297{ return relate(Box(p)); }
Relationship relate(LonLat const &p) const
Definition: Box.h:297

◆ relate() [6/6]

Relationship lsst::sphgeom::Box::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 317 of file Box.h.

317 {
318 // Dispatch on the type of r.
319 return invert(r.relate(*this));
320 }

Member Data Documentation

◆ TYPE_CODE

constexpr uint8_t lsst::sphgeom::Box::TYPE_CODE = 'b'
staticconstexpr

Definition at line 56 of file Box.h.


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