lsst.sphgeom g1081da9e2a+62d12e78cb
Loading...
Searching...
No Matches
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) {
60 return Box(NormalizedAngleInterval::fromDegrees(lon1, lon2),
61 AngleInterval::fromDegrees(lat1, lat2));
62 }
63
64 static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
65 return Box(NormalizedAngleInterval::fromRadians(lon1, lon2),
66 AngleInterval::fromRadians(lat1, lat2));
67 }
68
69 static Box empty() { return Box(); }
70
71 static Box full() { return Box(allLongitudes(), allLatitudes()); }
72
78
82 return NormalizedAngleInterval::full();
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) :
115 _lon(NormalizedAngleInterval(p.getLon()).dilatedBy(w)),
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
303 std::unique_ptr<Region> clone() const override {
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
340 static std::unique_ptr<Box> decode(std::vector<uint8_t> const & s) {
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.
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.
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition: Relationship.h:35
Relationship invert(Relationship r)
Definition: Relationship.h:55
This file declares a class for representing unit vectors in ℝ³.
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:40
Definition: Angle.h:43
Definition: Box3d.h:42
Definition: Box.h:54
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
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
Definition: Box.cc:43
Box()
This constructor creates an empty box.
Definition: Box.h:92
std::vector< uint8_t > encode() const override
Definition: Box.cc:447
NormalizedAngle getWidth() const
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
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(LonLat const &p1, LonLat const &p2)
Definition: Box.h:105
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition: Box.h:145
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition: Box.h:311
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
bool isFull() const
Definition: Box.h:155
Box & dilateBy(Angle r)
Definition: Box.cc:78
Angle getHeight() const
Definition: Box.h:169
LonLat getCenter() const
Definition: Box.h:159
Box(LonLat const &p, Angle w, Angle h)
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()
Definition: Box.h:81
Box & clipTo(Box const &x)
Definition: Box.h:227
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
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
Definition: Box.h:240
Box & expandTo(LonLat const &x)
Definition: Box.h:246
static AngleInterval allLatitudes()
Definition: Box.h:87
bool contains(LonLat const &x) const
Definition: Box.h:174
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
Box & clipTo(LonLat const &x)
Definition: Box.h:217
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
Definition: Circle.h:46
bool isWithin(Scalar x) const
Definition: Interval.h:140
Scalar getSize() const
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
Definition: Interval.h:89
Interval & expandTo(Scalar x)
Definition: Interval.h:192
bool contains(Scalar x) const
Definition: Interval.h:98
Definition: LonLat.h:48
Definition: NormalizedAngleInterval.h:57
bool isFull() const
isFull returns true if this interval contains all normalized angles.
Definition: NormalizedAngleInterval.h:129
NormalizedAngleInterval & clipTo(NormalizedAngle x)
clipTo shrinks this interval until all its points are in x.
Definition: NormalizedAngleInterval.h:203
NormalizedAngle getCenter() const
Definition: NormalizedAngleInterval.h:139
Relationship relate(NormalizedAngle x) const
Definition: NormalizedAngleInterval.cc:88
NormalizedAngle getSize() const
Definition: NormalizedAngleInterval.h:145
NormalizedAngleInterval & expandTo(NormalizedAngle x)
Definition: NormalizedAngleInterval.cc:189
bool intersects(NormalizedAngle x) const
Definition: NormalizedAngleInterval.h:173
bool isWithin(NormalizedAngle x) const
Definition: NormalizedAngleInterval.h:185
bool contains(NormalizedAngle x) const
Definition: NormalizedAngleInterval.h:150
bool isEmpty() const
Definition: NormalizedAngleInterval.h:126
Definition: NormalizedAngle.h:43
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.
Definition: UnitVector3d.h:55