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
Box.h
Go to the documentation of this file.
1/*
2 * LSST Data Management System
3 * Copyright 2014-2015 AURA/LSST.
4 *
5 * This product includes software developed by the
6 * LSST Project (http://www.lsst.org/).
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the LSST License Statement and
19 * the GNU General Public License along with this program. If not,
20 * see <https://www.lsstcorp.org/LegalNotices/>.
21 */
22
23#ifndef LSST_SPHGEOM_BOX_H_
24#define LSST_SPHGEOM_BOX_H_
25
29
30#include <iosfwd>
31
32#include "AngleInterval.h"
33#include "LonLat.h"
35#include "Region.h"
36#include "UnitVector3d.h"
37
38
39namespace lsst {
40namespace sphgeom {
41
54class Box : public Region {
55public:
56 static constexpr uint8_t TYPE_CODE = 'b';
57
58 // Factory functions
59 static Box fromDegrees(double lon1, double lat1, double lon2, double lat2) {
61 AngleInterval::fromDegrees(lat1, lat2));
62 }
63
64 static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
66 AngleInterval::fromRadians(lat1, lat2));
67 }
68
69 static Box empty() { return Box(); }
70
71 static Box full() { return Box(allLongitudes(), allLatitudes()); }
72
78
83 }
84
88 return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
89 }
90
92 Box() {}
93
95 explicit Box(LonLat const & p) :
96 _lon(p.getLon()),
97 _lat(p.getLat())
98 {
99 _enforceInvariants();
100 }
101
105 Box(LonLat const & p1, LonLat const & p2) :
106 _lon(p1.getLon(), p2.getLon()),
107 _lat(p1.getLat(), p2.getLat())
108 {
109 _enforceInvariants();
110 }
111
114 Box(LonLat const & p, Angle w, Angle h) :
116 _lat(AngleInterval(p.getLat()).dilatedBy(h))
117 {
118 _enforceInvariants();
119 }
120
123 Box(NormalizedAngleInterval const & lon, AngleInterval const & lat) :
124 _lon(lon),
125 _lat(lat)
126 {
127 _enforceInvariants();
128 }
129
131 bool operator==(Box const & b) const {
132 return _lon == b._lon && _lat == b._lat;
133 }
134
135 bool operator!=(Box const & b) const { return !(*this == b); }
136
138 bool operator==(LonLat const & p) const {
139 return _lat == p.getLat() && _lon == p.getLon();
140 }
141
142 bool operator!=(LonLat const & p) const { return !(*this == p); }
143
145 NormalizedAngleInterval const & getLon() const { return _lon; }
146
148 AngleInterval const & getLat() const { return _lat; }
149
151 bool isEmpty() const { return _lat.isEmpty(); }
152
155 bool isFull() const { return _lon.isFull() && _lat == allLatitudes(); }
156
160 return LonLat(_lon.getCenter(), _lat.getCenter());
161 }
162
165 NormalizedAngle getWidth() const { return _lon.getSize(); }
166
169 Angle getHeight() const { return _lat.getSize(); }
170
174 bool contains(LonLat const & x) const {
175 return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
176 }
177
178 bool contains(Box const & x) const {
179 return _lat.contains(x._lat) && _lon.contains(x._lon);
180 }
182
186 bool isDisjointFrom(LonLat const & x) const { return !intersects(x); }
187
188 bool isDisjointFrom(Box const & x) const { return !intersects(x); }
190
194 bool intersects(LonLat const & x) const {
195 return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
196 }
197
198 bool intersects(Box const & x) const {
199 return _lat.intersects(x._lat) && _lon.intersects(x._lon);
200 }
202
206 bool isWithin(LonLat const & x) const {
207 return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
208 }
209
210 bool isWithin(Box const & x) const {
211 return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
212 }
214
217 Box & clipTo(LonLat const & x) {
218 _lon.clipTo(x.getLon());
219 _lat.clipTo(x.getLat());
220 _enforceInvariants();
221 return *this;
222 }
223
227 Box & clipTo(Box const & x) {
228 _lon.clipTo(x.getLon());
229 _lat.clipTo(x.getLat());
230 _enforceInvariants();
231 return *this;
232 }
233
235 Box clippedTo(LonLat const & x) const { return Box(*this).clipTo(x); }
236
240 Box clippedTo(Box const & x) const { return Box(*this).clipTo(x); }
241
246 Box & expandTo(LonLat const & x) {
247 _lon.expandTo(x.getLon());
248 _lat.expandTo(x.getLat());
249 return *this;
250 }
251
252 Box & expandTo(Box const & x) {
253 _lon.expandTo(x.getLon());
254 _lat.expandTo(x.getLat());
255 return *this;
256 }
258
263 Box expandedTo(LonLat const & x) const { return Box(*this).expandTo(x); }
264 Box expandedTo(Box const & x) const { return Box(*this).expandTo(x); }
266
272 Box & dilateBy(Angle r);
273 Box dilatedBy(Angle r) const { return Box(*this).dilateBy(r); }
274
290 Box & dilateBy(Angle w, Angle h);
291 Box dilatedBy(Angle w, Angle h) const { return Box(*this).dilateBy(w, h); }
292 Box & erodeBy(Angle r) { return dilateBy(-r); }
293 Box & erodeBy(Angle w, Angle h) { return dilateBy(-w, -h); }
294 Box erodedBy(Angle r) const { return dilatedBy(-r); }
295 Box erodedBy(Angle w, Angle h) const { return dilatedBy(-w, -h); }
296
297 Relationship relate(LonLat const & p) const { return relate(Box(p)); }
298
300 double getArea() const;
301
302 // Region interface
304 return std::unique_ptr<Box>(new Box(*this));
305 }
306
307 Box getBoundingBox() const override { return *this; }
308 Box3d getBoundingBox3d() const override;
309 Circle getBoundingCircle() const override;
310
311 bool contains(UnitVector3d const & v) const override {
312 return contains(LonLat(v));
313 }
314
315 using Region::contains;
316
317 Relationship relate(Region const & r) const override {
318 // Dispatch on the type of r.
319 return invert(r.relate(*this));
320 }
321
322 Relationship relate(Box const & b) const override {
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 }
331
332 Relationship relate(Circle const &) const override;
333 Relationship relate(ConvexPolygon const &) const override;
334 Relationship relate(Ellipse const &) const override;
335
336 std::vector<uint8_t> encode() const override;
337
341 return decode(s.data(), s.size());
342 }
343 static std::unique_ptr<Box> decode(uint8_t const * buffer, size_t n);
345
346private:
347 static constexpr size_t ENCODED_SIZE = 33;
348
349 void _enforceInvariants() {
350 // Make sure that _lat ⊆ [-π/2, π/2].
351 _lat.clipTo(allLatitudes());
352 // Make sure that both longitude and latitude intervals are
353 // empty, or neither is. This simplifies the implementation
354 // of the spatial relation tests.
355 if (_lat.isEmpty()) {
357 } else if (_lon.isEmpty()) {
358 _lat = AngleInterval();
359 }
360 }
361
362 NormalizedAngleInterval _lon;
363 AngleInterval _lat;
364};
365
366std::ostream & operator<<(std::ostream &, Box const &);
367
368}} // namespace lsst::sphgeom
369
370#endif // LSST_SPHGEOM_BOX_H_
This file defines a class for representing angle intervals.
double x
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:43
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:40
static AngleInterval fromDegrees(double x, double y)
Definition: AngleInterval.h:44
static AngleInterval fromRadians(double x, double y)
Definition: AngleInterval.h:49
Box3d represents a box in ℝ³.
Definition: Box3d.h:42
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition: Box.h:54
Relationship relate(Box const &b) const override
Definition: Box.h:322
Box erodedBy(Angle w, Angle h) const
Definition: Box.h:295
Box clippedTo(LonLat const &x) const
clippedTo returns the intersection of this box and x.
Definition: Box.h:235
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
Definition: Box.h:307
bool operator==(LonLat const &p) const
A box is equal to a point p if it contains only p.
Definition: Box.h:138
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition: Box.h:148
Box dilatedBy(Angle r) const
Definition: Box.h:273
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
Box & erodeBy(Angle r)
Definition: Box.h:292
Box()
This constructor creates an empty box.
Definition: Box.h:92
bool operator!=(LonLat const &p) const
Definition: Box.h:142
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
Definition: Box.cc:447
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition: Box.h:165
double getArea() const
getArea returns the area of this box in steradians.
Definition: Box.cc:115
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
Definition: Box.cc:127
static Box fromRadians(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:64
bool isWithin(Box const &x) const
Definition: Box.h:210
Box expandedTo(LonLat const &x) const
Definition: Box.h:263
bool operator==(Box const &b) const
Two boxes are equal if they contain the same points.
Definition: Box.h:131
Box dilatedBy(Angle w, Angle h) const
Definition: Box.h:291
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:105
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition: Box.h:145
bool operator!=(Box const &b) const
Definition: Box.h:135
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition: Box.h:311
Relationship relate(LonLat const &p) const
Definition: Box.h:297
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition: Box.h:340
bool isDisjointFrom(LonLat const &x) const
Definition: Box.h:186
Box(LonLat const &p)
This constructor creates a box containing a single point.
Definition: Box.h:95
Box & expandTo(Box const &x)
Definition: Box.h:252
static Box empty()
Definition: Box.h:69
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition: Box.h:155
Box expandedTo(Box const &x) const
Definition: Box.h:264
Box & erodeBy(Angle w, Angle h)
Definition: Box.h:293
static constexpr uint8_t TYPE_CODE
Definition: Box.h:56
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition: Box.cc:78
Angle getHeight() const
getHeight returns the height in latitude angle of this box.
Definition: Box.h:169
LonLat getCenter() const
getCenter returns the center of this box.
Definition: Box.h:159
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:114
std::unique_ptr< Region > clone() const override
clone returns a deep copy of this region.
Definition: Box.h:303
static NormalizedAngleInterval allLongitudes()
allLongitudes returns a normalized angle interval containing all valid longitude angles.
Definition: Box.h:81
bool isDisjointFrom(Box const &x) const
Definition: Box.h:188
Box & clipTo(Box const &x)
x.clipTo(y) sets x to the smallest box containing the intersection of x and y.
Definition: Box.h:227
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
This constructor creates a box spanning the given longitude and latitude intervals.
Definition: Box.h:123
bool isWithin(LonLat const &x) const
Definition: Box.h:206
Relationship relate(Region const &r) const override
Definition: Box.h:317
Box clippedTo(Box const &x) const
clippedTo returns the smallest box containing the intersection of this box and x.
Definition: Box.h:240
bool intersects(Box const &x) const
Definition: Box.h:198
Box erodedBy(Angle r) const
Definition: Box.h:294
Box & expandTo(LonLat const &x)
Definition: Box.h:246
static AngleInterval allLatitudes()
allLatitudes returns an angle interval containing all valid latitude angles.
Definition: Box.h:87
bool contains(LonLat const &x) const
Definition: Box.h:174
static Box fromDegrees(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:59
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
Box & clipTo(LonLat const &x)
clipTo shrinks this box until it contains only x.
Definition: Box.h:217
static Box full()
Definition: Box.h:71
bool contains(Box const &x) const
Definition: Box.h:178
bool intersects(LonLat const &x) const
Definition: Box.h:194
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition: Box.cc:187
Circle is a circular region on the unit sphere that contains its boundary.
Definition: Circle.h:46
ConvexPolygon is a closed convex polygon on the unit sphere.
Definition: ConvexPolygon.h:57
Ellipse is an elliptical region on the sphere.
Definition: Ellipse.h:170
bool isWithin(Scalar x) const
Definition: Interval.h:140
Scalar getSize() const
getSize returns the size (length, width) of this interval.
Definition: Interval.h:93
Interval & clipTo(Scalar x)
Definition: Interval.h:159
bool isEmpty() const
isEmpty returns true if this interval does not contain any points.
Definition: Interval.h:83
Relationship relate(Scalar x) const
Definition: Interval.h:249
bool intersects(Scalar x) const
Definition: Interval.h:130
Scalar getCenter() const
getCenter returns the center of this interval.
Definition: Interval.h:89
Interval & expandTo(Scalar x)
Definition: Interval.h:192
bool contains(Scalar x) const
Definition: Interval.h:98
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition: LonLat.h:48
Angle getLat() const
Definition: LonLat.h:90
NormalizedAngle getLon() const
Definition: LonLat.h:88
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:79
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.
Definition: UnitVector3d.h:55
T data(T... args)
lsst::geom::Angle Angle
Definition: misc.h:33
std::ostream & operator<<(std::ostream &, Angle const &)
Definition: Angle.cc:34
constexpr double PI
Definition: constants.h:36
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55
A base class for image defects.
T size(T... args)
double w
Definition: CoaddPsf.cc:69