LSST Applications g011c388f00+c533e7e796,g0265f82a02+71b8ded0d6,g16a3bce237+71b8ded0d6,g2079a07aa2+b9108c1c87,g2bbee38e9b+71b8ded0d6,g337abbeb29+71b8ded0d6,g3ddfee87b4+efeeb9cceb,g44050f54f7+816a004954,g4cf46543a9+ac9bf1619d,g50ff169b8f+8309cf5058,g52b1c1532d+43dac7135f,g858d7b2824+816a004954,g8a8a8dda67+43dac7135f,g99855d9996+36230435de,g9cb17f706c+56afb287bb,g9ddcbc5298+389b8f2b7e,ga1e77700b3+4bafba478f,ga8c6da7877+9a92598c84,gae46bcf261+71b8ded0d6,gb0e22166c9+713927f999,gb700894bec+0b6c79d923,gb8350603e9+a03320826c,gba4ed39666+e464e2e6f0,gbeb006f7da+8cd302297b,gc86a011abf+816a004954,gcf0d15dbbd+efeeb9cceb,gd0e876f1fb+efeeb9cceb,gd162630629+3eacc90e0c,gd44f2fa1a7+82b768a15d,gd8a3c24633+eaa4ad6639,gdaeeff99f8+6b435c3f92,ge2eec9bf53+fad368631c,ge79ae78c31+71b8ded0d6,gee10cc3b42+43dac7135f,gf1cff7945b+816a004954,w.2024.08
LSST Data Management Base Package
Loading...
Searching...
No Matches
Box.h
Go to the documentation of this file.
1/*
2 * This file is part of sphgeom.
3 *
4 * Developed for the LSST Data Management System.
5 * This product includes software developed by the LSST Project
6 * (http://www.lsst.org).
7 * See the COPYRIGHT file at the top-level directory of this distribution
8 * for details of code ownership.
9 *
10 * This software is dual licensed under the GNU General Public License and also
11 * under a 3-clause BSD license. Recipients may choose which of these licenses
12 * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 * respectively. If you choose the GPL option then the following text applies
14 * (but note that there is still no warranty even if you opt for BSD instead):
15 *
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 */
29
30#ifndef LSST_SPHGEOM_BOX_H_
31#define LSST_SPHGEOM_BOX_H_
32
36
37#include <iosfwd>
38
39#include "AngleInterval.h"
40#include "LonLat.h"
42#include "Region.h"
43#include "UnitVector3d.h"
44
45
46namespace lsst {
47namespace sphgeom {
48
61class Box : public Region {
62public:
63 static constexpr uint8_t TYPE_CODE = 'b';
64
65 // Factory functions
66 static Box fromDegrees(double lon1, double lat1, double lon2, double lat2) {
68 AngleInterval::fromDegrees(lat1, lat2));
69 }
70
71 static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
73 AngleInterval::fromRadians(lat1, lat2));
74 }
75
76 static Box empty() { return Box(); }
77
78 static Box full() { return Box(allLongitudes(), allLatitudes()); }
79
85
91
95 return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
96 }
97
99 Box() {}
100
102 explicit Box(LonLat const & p) :
103 _lon(p.getLon()),
104 _lat(p.getLat())
105 {
106 _enforceInvariants();
107 }
108
112 Box(LonLat const & p1, LonLat const & p2) :
113 _lon(p1.getLon(), p2.getLon()),
114 _lat(p1.getLat(), p2.getLat())
115 {
116 _enforceInvariants();
117 }
118
121 Box(LonLat const & p, Angle w, Angle h) :
123 _lat(AngleInterval(p.getLat()).dilatedBy(h))
124 {
125 _enforceInvariants();
126 }
127
130 Box(NormalizedAngleInterval const & lon, AngleInterval const & lat) :
131 _lon(lon),
132 _lat(lat)
133 {
134 _enforceInvariants();
135 }
136
138 bool operator==(Box const & b) const {
139 return _lon == b._lon && _lat == b._lat;
140 }
141
142 bool operator!=(Box const & b) const { return !(*this == b); }
143
145 bool operator==(LonLat const & p) const {
146 return _lat == p.getLat() && _lon == p.getLon();
147 }
148
149 bool operator!=(LonLat const & p) const { return !(*this == p); }
150
152 NormalizedAngleInterval const & getLon() const { return _lon; }
153
155 AngleInterval const & getLat() const { return _lat; }
156
158 bool isEmpty() const { return _lat.isEmpty(); }
159
162 bool isFull() const { return _lon.isFull() && _lat == allLatitudes(); }
163
167 return LonLat(_lon.getCenter(), _lat.getCenter());
168 }
169
172 NormalizedAngle getWidth() const { return _lon.getSize(); }
173
176 Angle getHeight() const { return _lat.getSize(); }
177
181 bool contains(LonLat const & x) const {
182 return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
183 }
184
185 bool contains(Box const & x) const {
186 return _lat.contains(x._lat) && _lon.contains(x._lon);
187 }
189
193 bool isDisjointFrom(LonLat const & x) const { return !intersects(x); }
194
195 bool isDisjointFrom(Box const & x) const { return !intersects(x); }
197
201 bool intersects(LonLat const & x) const {
202 return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
203 }
204
205 bool intersects(Box const & x) const {
206 return _lat.intersects(x._lat) && _lon.intersects(x._lon);
207 }
209
213 bool isWithin(LonLat const & x) const {
214 return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
215 }
216
217 bool isWithin(Box const & x) const {
218 return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
219 }
221
224 Box & clipTo(LonLat const & x) {
225 _lon.clipTo(x.getLon());
226 _lat.clipTo(x.getLat());
227 _enforceInvariants();
228 return *this;
229 }
230
234 Box & clipTo(Box const & x) {
235 _lon.clipTo(x.getLon());
236 _lat.clipTo(x.getLat());
237 _enforceInvariants();
238 return *this;
239 }
240
242 Box clippedTo(LonLat const & x) const { return Box(*this).clipTo(x); }
243
247 Box clippedTo(Box const & x) const { return Box(*this).clipTo(x); }
248
253 Box & expandTo(LonLat const & x) {
254 _lon.expandTo(x.getLon());
255 _lat.expandTo(x.getLat());
256 return *this;
257 }
258
259 Box & expandTo(Box const & x) {
260 _lon.expandTo(x.getLon());
261 _lat.expandTo(x.getLat());
262 return *this;
263 }
265
270 Box expandedTo(LonLat const & x) const { return Box(*this).expandTo(x); }
271 Box expandedTo(Box const & x) const { return Box(*this).expandTo(x); }
273
279 Box & dilateBy(Angle r);
280 Box dilatedBy(Angle r) const { return Box(*this).dilateBy(r); }
281
297 Box & dilateBy(Angle w, Angle h);
298 Box dilatedBy(Angle w, Angle h) const { return Box(*this).dilateBy(w, h); }
299 Box & erodeBy(Angle r) { return dilateBy(-r); }
300 Box & erodeBy(Angle w, Angle h) { return dilateBy(-w, -h); }
301 Box erodedBy(Angle r) const { return dilatedBy(-r); }
302 Box erodedBy(Angle w, Angle h) const { return dilatedBy(-w, -h); }
303
304 Relationship relate(LonLat const & p) const { return relate(Box(p)); }
305
307 double getArea() const;
308
309 // Region interface
311 return std::unique_ptr<Box>(new Box(*this));
312 }
313
314 Box getBoundingBox() const override { return *this; }
315 Box3d getBoundingBox3d() const override;
316 Circle getBoundingCircle() const override;
317
318 bool contains(UnitVector3d const & v) const override {
319 return contains(LonLat(v));
320 }
321
322 using Region::contains;
323
324 Relationship relate(Region const & r) const override {
325 // Dispatch on the type of r.
326 return invert(r.relate(*this));
327 }
328
329 Relationship relate(Box const & b) const override {
330 Relationship r1 = _lon.relate(b._lon);
331 Relationship r2 = _lat.relate(b._lat);
332 // If the box longitude or latitude intervals are disjoint, then the
333 // boxes are disjoint. The other spatial relationships must hold for
334 // both the longitude and latitude intervals in order to hold for the
335 // boxes.
336 return ((r1 & r2) & (CONTAINS | WITHIN)) | ((r1 | r2) & DISJOINT);
337 }
338
339 Relationship relate(Circle const &) const override;
340 Relationship relate(ConvexPolygon const &) const override;
341 Relationship relate(Ellipse const &) const override;
342
343 std::vector<uint8_t> encode() const override;
344
348 return decode(s.data(), s.size());
349 }
350 static std::unique_ptr<Box> decode(uint8_t const * buffer, size_t n);
352
353private:
354 static constexpr size_t ENCODED_SIZE = 33;
355
356 void _enforceInvariants() {
357 // Make sure that _lat ⊆ [-π/2, π/2].
358 _lat.clipTo(allLatitudes());
359 // Make sure that both longitude and latitude intervals are
360 // empty, or neither is. This simplifies the implementation
361 // of the spatial relation tests.
362 if (_lat.isEmpty()) {
364 } else if (_lon.isEmpty()) {
365 _lat = AngleInterval();
366 }
367 }
368
369 NormalizedAngleInterval _lon;
370 AngleInterval _lat;
371};
372
373std::ostream & operator<<(std::ostream &, Box const &);
374
375}} // namespace lsst::sphgeom
376
377#endif // LSST_SPHGEOM_BOX_H_
This file defines a class for representing angle intervals.
This file contains a class representing spherical coordinates.
This file declares a class representing closed intervals of normalized angles, i.e.
This file defines an interface for spherical regions.
table::Key< int > b
This file declares a class for representing unit vectors in ℝ³.
Angle represents an angle in radians.
Definition Angle.h:50
AngleInterval represents closed intervals of arbitrary angles.
static AngleInterval fromDegrees(double x, double y)
static AngleInterval fromRadians(double x, double y)
Box3d represents a box in ℝ³.
Definition Box3d.h:49
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition Box.h:61
Relationship relate(Box const &b) const override
Definition Box.h:329
Box erodedBy(Angle w, Angle h) const
Definition Box.h:302
Box clippedTo(LonLat const &x) const
clippedTo returns the intersection of this box and x.
Definition Box.h:242
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
Definition Box.h:314
bool operator==(LonLat const &p) const
A box is equal to a point p if it contains only p.
Definition Box.h:145
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition Box.h:155
Box dilatedBy(Angle r) const
Definition Box.h:280
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
Box & erodeBy(Angle r)
Definition Box.h:299
Box()
This constructor creates an empty box.
Definition Box.h:99
bool operator!=(LonLat const &p) const
Definition Box.h:149
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
Definition Box.cc:454
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition Box.h:172
double getArea() const
getArea returns the area of this box in steradians.
Definition Box.cc:122
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
Definition Box.cc:134
static Box fromRadians(double lon1, double lat1, double lon2, double lat2)
Definition Box.h:71
bool isWithin(Box const &x) const
Definition Box.h:217
Box expandedTo(LonLat const &x) const
Definition Box.h:270
bool operator==(Box const &b) const
Two boxes are equal if they contain the same points.
Definition Box.h:138
Box dilatedBy(Angle w, Angle h) const
Definition Box.h:298
Box(LonLat const &p1, LonLat const &p2)
This constructor creates a box spanning the longitude interval [p1.getLon(), p2.getLon()] and latitud...
Definition Box.h:112
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition Box.h:152
bool operator!=(Box const &b) const
Definition Box.h:142
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition Box.h:318
Relationship relate(LonLat const &p) const
Definition Box.h:304
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition Box.h:347
bool isDisjointFrom(LonLat const &x) const
Definition Box.h:193
Box(LonLat const &p)
This constructor creates a box containing a single point.
Definition Box.h:102
Box & expandTo(Box const &x)
Definition Box.h:259
static Box empty()
Definition Box.h:76
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition Box.h:162
Box expandedTo(Box const &x) const
Definition Box.h:271
Box & erodeBy(Angle w, Angle h)
Definition Box.h:300
static constexpr uint8_t TYPE_CODE
Definition Box.h:63
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition Box.cc:85
Angle getHeight() const
getHeight returns the height in latitude angle of this box.
Definition Box.h:176
LonLat getCenter() const
getCenter returns the center of this box.
Definition Box.h:166
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 l...
Definition Box.h:121
std::unique_ptr< Region > clone() const override
clone returns a deep copy of this region.
Definition Box.h:310
static NormalizedAngleInterval allLongitudes()
allLongitudes returns a normalized angle interval containing all valid longitude angles.
Definition Box.h:88
bool isDisjointFrom(Box const &x) const
Definition Box.h:195
Box & clipTo(Box const &x)
x.clipTo(y) sets x to the smallest box containing the intersection of x and y.
Definition Box.h:234
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
This constructor creates a box spanning the given longitude and latitude intervals.
Definition Box.h:130
bool isWithin(LonLat const &x) const
Definition Box.h:213
Relationship relate(Region const &r) const override
Definition Box.h:324
Box clippedTo(Box const &x) const
clippedTo returns the smallest box containing the intersection of this box and x.
Definition Box.h:247
bool intersects(Box const &x) const
Definition Box.h:205
Box erodedBy(Angle r) const
Definition Box.h:301
Box & expandTo(LonLat const &x)
Definition Box.h:253
static AngleInterval allLatitudes()
allLatitudes returns an angle interval containing all valid latitude angles.
Definition Box.h:94
bool contains(LonLat const &x) const
Definition Box.h:181
static Box fromDegrees(double lon1, double lat1, double lon2, double lat2)
Definition Box.h:66
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition Box.h:158
Box & clipTo(LonLat const &x)
clipTo shrinks this box until it contains only x.
Definition Box.h:224
static Box full()
Definition Box.h:78
bool contains(Box const &x) const
Definition Box.h:185
bool intersects(LonLat const &x) const
Definition Box.h:201
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition Box.cc:194
Circle is a circular region on the unit sphere that contains its boundary.
Definition Circle.h:53
ConvexPolygon is a closed convex polygon on the unit sphere.
Ellipse is an elliptical region on the sphere.
Definition Ellipse.h:177
bool isWithin(Scalar x) const
Definition Interval.h:147
Scalar getSize() const
getSize returns the size (length, width) of this interval.
Definition Interval.h:100
Interval & clipTo(Scalar x)
Definition Interval.h:166
bool isEmpty() const
isEmpty returns true if this interval does not contain any points.
Definition Interval.h:90
Relationship relate(Scalar x) const
Definition Interval.h:256
bool intersects(Scalar x) const
Definition Interval.h:137
Scalar getCenter() const
getCenter returns the center of this interval.
Definition Interval.h:96
Interval & expandTo(Scalar x)
Definition Interval.h:199
bool contains(Scalar x) const
Definition Interval.h:105
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition LonLat.h:55
Angle getLat() const
Definition LonLat.h:97
NormalizedAngle getLon() const
Definition LonLat.h:95
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...
NormalizedAngleInterval represents closed intervals of normalized angles, i.e.
bool isFull() const
isFull returns true if this interval contains all normalized angles.
NormalizedAngleInterval & clipTo(NormalizedAngle x)
clipTo shrinks this interval until all its points are in x.
NormalizedAngle getCenter() const
getCenter returns the center of this interval.
Relationship relate(NormalizedAngle x) const
NormalizedAngle getSize() const
getSize returns the size (length, width) of this interval.
NormalizedAngleInterval & expandTo(NormalizedAngle x)
static NormalizedAngleInterval fromDegrees(double a, double b)
static NormalizedAngleInterval fromRadians(double a, double b)
static NormalizedAngleInterval full()
bool isEmpty() const
isEmpty returns true if this interval does not contain any normalized angles.
Region is a minimal interface for 2-dimensional regions on the unit sphere.
Definition Region.h:86
virtual Relationship relate(Region const &) const =0
virtual bool contains(UnitVector3d const &) const =0
contains tests whether the given unit vector is inside this region.
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
T data(T... args)
std::ostream & operator<<(std::ostream &, Angle const &)
Definition Angle.cc:41
constexpr double PI
Definition constants.h:43
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
T size(T... args)
double w
Definition CoaddPsf.cc:69