lsst.sphgeom g04536d8304+b0138be388
 
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#include <cstdint>
39
40#include "AngleInterval.h"
41#include "LonLat.h"
43#include "Region.h"
44#include "UnitVector3d.h"
45
46
47namespace lsst {
48namespace sphgeom {
49
62class Box : public Region {
63public:
64 static constexpr std::uint8_t TYPE_CODE = 'b';
65
66 // Factory functions
67 static Box fromDegrees(double lon1, double lat1, double lon2, double lat2) {
68 return Box(NormalizedAngleInterval::fromDegrees(lon1, lon2),
69 AngleInterval::fromDegrees(lat1, lat2));
70 }
71
72 static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
73 return Box(NormalizedAngleInterval::fromRadians(lon1, lon2),
74 AngleInterval::fromRadians(lat1, lat2));
75 }
76
77 static Box empty() { return Box(); }
78
79 static Box full() { return Box(allLongitudes(), allLatitudes()); }
80
86
90 return NormalizedAngleInterval::full();
91 }
92
96 return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
97 }
98
100 Box() {}
101
103 explicit Box(LonLat const & p) :
104 _lon(p.getLon()),
105 _lat(p.getLat())
106 {
107 _enforceInvariants();
108 }
109
113 Box(LonLat const & p1, LonLat const & p2) :
114 _lon(p1.getLon(), p2.getLon()),
115 _lat(p1.getLat(), p2.getLat())
116 {
117 _enforceInvariants();
118 }
119
122 Box(LonLat const & p, Angle w, Angle h) :
123 _lon(NormalizedAngleInterval(p.getLon()).dilatedBy(w)),
124 _lat(AngleInterval(p.getLat()).dilatedBy(h))
125 {
126 _enforceInvariants();
127 }
128
131 Box(NormalizedAngleInterval const & lon, AngleInterval const & lat) :
132 _lon(lon),
133 _lat(lat)
134 {
135 _enforceInvariants();
136 }
137
139 bool operator==(Box const & b) const {
140 return _lon == b._lon && _lat == b._lat;
141 }
142
143 bool operator!=(Box const & b) const { return !(*this == b); }
144
146 bool operator==(LonLat const & p) const {
147 return _lat == p.getLat() && _lon == p.getLon();
148 }
149
150 bool operator!=(LonLat const & p) const { return !(*this == p); }
151
153 NormalizedAngleInterval const & getLon() const { return _lon; }
154
156 AngleInterval const & getLat() const { return _lat; }
157
159 bool isEmpty() const override { return _lat.isEmpty(); }
160
163 bool isFull() const { return _lon.isFull() && _lat == allLatitudes(); }
164
168 return LonLat(_lon.getCenter(), _lat.getCenter());
169 }
170
173 NormalizedAngle getWidth() const { return _lon.getSize(); }
174
177 Angle getHeight() const { return _lat.getSize(); }
178
182 bool contains(LonLat const & x) const {
183 return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
184 }
185
186 bool contains(Box const & x) const {
187 return _lat.contains(x._lat) && _lon.contains(x._lon);
188 }
190
194 bool isDisjointFrom(LonLat const & x) const { return !intersects(x); }
195
196 bool isDisjointFrom(Box const & x) const { return !intersects(x); }
198
202 bool intersects(LonLat const & x) const {
203 return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
204 }
205
206 bool intersects(Box const & x) const {
207 return _lat.intersects(x._lat) && _lon.intersects(x._lon);
208 }
210
214 bool isWithin(LonLat const & x) const {
215 return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
216 }
217
218 bool isWithin(Box const & x) const {
219 return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
220 }
222
225 Box & clipTo(LonLat const & x) {
226 _lon.clipTo(x.getLon());
227 _lat.clipTo(x.getLat());
228 _enforceInvariants();
229 return *this;
230 }
231
235 Box & clipTo(Box const & x) {
236 _lon.clipTo(x.getLon());
237 _lat.clipTo(x.getLat());
238 _enforceInvariants();
239 return *this;
240 }
241
243 Box clippedTo(LonLat const & x) const { return Box(*this).clipTo(x); }
244
248 Box clippedTo(Box const & x) const { return Box(*this).clipTo(x); }
249
254 Box & expandTo(LonLat const & x) {
255 _lon.expandTo(x.getLon());
256 _lat.expandTo(x.getLat());
257 return *this;
258 }
259
260 Box & expandTo(Box const & x) {
261 _lon.expandTo(x.getLon());
262 _lat.expandTo(x.getLat());
263 return *this;
264 }
266
271 Box expandedTo(LonLat const & x) const { return Box(*this).expandTo(x); }
272 Box expandedTo(Box const & x) const { return Box(*this).expandTo(x); }
274
280 Box & dilateBy(Angle r);
281 Box dilatedBy(Angle r) const { return Box(*this).dilateBy(r); }
282
298 Box & dilateBy(Angle w, Angle h);
299 Box dilatedBy(Angle w, Angle h) const { return Box(*this).dilateBy(w, h); }
300 Box & erodeBy(Angle r) { return dilateBy(-r); }
301 Box & erodeBy(Angle w, Angle h) { return dilateBy(-w, -h); }
302 Box erodedBy(Angle r) const { return dilatedBy(-r); }
303 Box erodedBy(Angle w, Angle h) const { return dilatedBy(-w, -h); }
304
305 Relationship relate(LonLat const & p) const { return relate(Box(p)); }
306
308 double getArea() const;
309
310 // Region interface
311 std::unique_ptr<Region> clone() const override {
312 return std::unique_ptr<Box>(new Box(*this));
313 }
314
315 Box getBoundingBox() const override { return *this; }
316 Box3d getBoundingBox3d() const override;
317 Circle getBoundingCircle() const override;
318
319 bool contains(UnitVector3d const & v) const override {
320 return contains(LonLat(v));
321 }
322
323 using Region::contains;
324
325 Relationship relate(Region const & r) const override {
326 // Dispatch on the type of r.
327 return invert(r.relate(*this));
328 }
329
330 Relationship relate(Box const & b) const override {
331 Relationship r1 = _lon.relate(b._lon);
332 Relationship r2 = _lat.relate(b._lat);
333 // If the box longitude or latitude intervals are disjoint, then the
334 // boxes are disjoint. The other spatial relationships must hold for
335 // both the longitude and latitude intervals in order to hold for the
336 // boxes.
337 return ((r1 & r2) & (CONTAINS | WITHIN)) | ((r1 | r2) & DISJOINT);
338 }
339
340 Relationship relate(Circle const &) const override;
341 Relationship relate(ConvexPolygon const &) const override;
342 Relationship relate(Ellipse const &) const override;
343
344 TriState overlaps(Region const& other) const override {
345 return other.overlaps(*this);
346 }
347 TriState overlaps(Box const &) const override;
348 TriState overlaps(Circle const &) const override;
349 TriState overlaps(ConvexPolygon const &) const override;
350 TriState overlaps(Ellipse const &) const override;
351
352 std::vector<std::uint8_t> encode() const override;
353
356 static std::unique_ptr<Box> decode(std::vector<std::uint8_t> const & s) {
357 return decode(s.data(), s.size());
358 }
359 static std::unique_ptr<Box> decode(std::uint8_t const * buffer, size_t n);
361
362private:
363 static constexpr size_t ENCODED_SIZE = 33;
364
365 void _enforceInvariants() {
366 // Make sure that _lat ⊆ [-π/2, π/2].
367 _lat.clipTo(allLatitudes());
368 // Make sure that both longitude and latitude intervals are
369 // empty, or neither is. This simplifies the implementation
370 // of the spatial relation tests.
371 if (_lat.isEmpty()) {
373 } else if (_lon.isEmpty()) {
374 _lat = AngleInterval();
375 }
376 }
377
378 NormalizedAngleInterval _lon;
379 AngleInterval _lat;
380};
381
382std::ostream & operator<<(std::ostream &, Box const &);
383
384}} // namespace lsst::sphgeom
385
386#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.
This file declares a class for representing unit vectors in ℝ³.
AngleInterval represents closed intervals of arbitrary angles.
Definition AngleInterval.h:47
Definition Angle.h:50
Definition Box3d.h:49
Definition Box.h:62
Box clippedTo(LonLat const &x) const
clippedTo returns the intersection of this box and x.
Definition Box.h:243
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
Definition Box.h:315
bool operator==(LonLat const &p) const
A box is equal to a point p if it contains only p.
Definition Box.h:146
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition Box.h:156
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
Definition Box.cc:50
Box()
This constructor creates an empty box.
Definition Box.h:100
NormalizedAngle getWidth() const
Definition Box.h:173
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
Box expandedTo(LonLat const &x) const
Definition Box.h:271
bool operator==(Box const &b) const
Two boxes are equal if they contain the same points.
Definition Box.h:139
Box(LonLat const &p1, LonLat const &p2)
Definition Box.h:113
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition Box.h:153
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition Box.h:319
bool isDisjointFrom(LonLat const &x) const
Definition Box.h:194
static std::unique_ptr< Box > decode(std::vector< std::uint8_t > const &s)
Definition Box.h:356
Box(LonLat const &p)
This constructor creates a box containing a single point.
Definition Box.h:103
bool isFull() const
Definition Box.h:163
std::vector< std::uint8_t > encode() const override
Definition Box.cc:474
bool isEmpty() const override
isEmpty returns true if this box does not contain any points.
Definition Box.h:159
Box & dilateBy(Angle r)
Definition Box.cc:85
Angle getHeight() const
Definition Box.h:177
LonLat getCenter() const
Definition Box.h:167
Box(LonLat const &p, Angle w, Angle h)
Definition Box.h:122
std::unique_ptr< Region > clone() const override
clone returns a deep copy of this region.
Definition Box.h:311
static NormalizedAngleInterval allLongitudes()
Definition Box.h:89
Box & clipTo(Box const &x)
Definition Box.h:235
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
Definition Box.h:131
bool isWithin(LonLat const &x) const
Definition Box.h:214
Relationship relate(Region const &r) const override
Definition Box.h:325
Box clippedTo(Box const &x) const
Definition Box.h:248
Box & expandTo(LonLat const &x)
Definition Box.h:254
static AngleInterval allLatitudes()
Definition Box.h:95
TriState overlaps(Region const &other) const override
Definition Box.h:344
bool contains(LonLat const &x) const
Definition Box.h:182
Box & clipTo(LonLat const &x)
Definition Box.h:225
bool intersects(LonLat const &x) const
Definition Box.h:202
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition Box.cc:194
Definition Circle.h:54
Definition ConvexPolygon.h:65
Definition Ellipse.h:177
bool isWithin(Scalar x) const
Definition Interval.h:147
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
Interval & expandTo(Scalar x)
Definition Interval.h:199
bool contains(Scalar x) const
Definition Interval.h:105
Definition LonLat.h:55
Definition NormalizedAngleInterval.h:64
Relationship relate(NormalizedAngle x) const
Definition NormalizedAngleInterval.cc:95
NormalizedAngleInterval & expandTo(NormalizedAngle x)
Definition NormalizedAngleInterval.cc:196
bool intersects(NormalizedAngle x) const
Definition NormalizedAngleInterval.h:180
bool isWithin(NormalizedAngle x) const
Definition NormalizedAngleInterval.h:192
bool contains(NormalizedAngle x) const
Definition NormalizedAngleInterval.h:157
bool isEmpty() const
Definition NormalizedAngleInterval.h:133
Definition NormalizedAngle.h:50
Definition Region.h:89
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.
virtual TriState overlaps(Region const &other) const =0
Definition Region.cc:59
Definition TriState.h:46
Definition UnitVector3d.h:62
Definition Angle.h:45
Relationship invert(Relationship r)
Definition Relationship.h:62
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition Relationship.h:42