lsst.sphgeom g161b0bc589+ac198e9f13
Interval.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_INTERVAL_H_
24#define LSST_SPHGEOM_INTERVAL_H_
25
28
29#include <algorithm>
30
31#include "Relationship.h"
32
33
34namespace lsst {
35namespace sphgeom {
36
47template <typename Derived, typename Scalar>
48class Interval {
49public:
51 Interval() : _a(1.0), _b(0.0) {}
52
54 explicit Interval(Scalar x) : _a(x), _b(x) {}
55
57 Interval(Scalar x, Scalar y) : _a(x), _b(y) {}
58
61 bool operator==(Interval const & i) const {
62 return (_a == i._a && _b == i._b) || (i.isEmpty() && isEmpty());
63 }
64
65 bool operator!=(Interval const & i) const { return !(*this == i); }
66
68 bool operator==(Scalar x) const {
69 return (_a == x && _b == x) || (x != x && isEmpty());
70 }
71
72 bool operator!=(Scalar x) const { return !(*this == x); }
73
76 Scalar getA() const { return _a; }
77
80 Scalar getB() const { return _b; }
81
83 bool isEmpty() const {
84 return !(_a <= _b); // returns true when _a and/or _b is NaN
85 }
86
89 Scalar getCenter() const { return 0.5 * (_a + _b); }
90
93 Scalar getSize() const { return _b - _a; }
94
98 bool contains(Scalar x) const {
99 return (_a <= x && x <= _b) || x != x;
100 }
101
102 bool contains(Interval const & x) const {
103 if (x.isEmpty()) {
104 return true;
105 } else if (isEmpty()) {
106 return false;
107 }
108 return _a <= x._a && _b >= x._b;
109 }
111
115 bool isDisjointFrom(Scalar x) const {
116 return !intersects(x);
117 }
118
119 bool isDisjointFrom(Interval const & x) const {
120 if (isEmpty() || x.isEmpty()) {
121 return true;
122 }
123 return _a > x._b || _b < x._a;
124 }
126
130 bool intersects(Scalar x) const { return _a <= x && x <= _b; }
131
132 bool intersects(Interval const & x) const {
133 return !isDisjointFrom(x);
134 }
136
140 bool isWithin(Scalar x) const {
141 return (_a == x && _b == x) || isEmpty();
142 }
143
144 bool isWithin(Interval const & x) const {
145 return x.contains(*this);
146 }
148
153 Relationship relate(Scalar x) const;
154 Relationship relate(Interval const & x) const;
156
159 Interval & clipTo(Scalar x) {
160 if (x != x) {
161 _a = x;
162 _b = x;
163 } else {
164 _a = std::max(_a, x);
165 _b = std::min(_b, x);
166 }
167 return *this;
168 }
169
170 Interval & clipTo(Interval const & x) {
171 if (x.isEmpty()) {
172 *this = x;
173 } else if (!isEmpty()) {
174 _a = std::max(_a, x._a);
175 _b = std::min(_b, x._b);
176 }
177 return *this;
178 }
180
183 Derived clippedTo(Scalar x) const { return Interval(*this).clipTo(x); }
184
185 Derived clippedTo(Interval const & x) const {
186 return Interval(*this).clipTo(x);
187 }
189
192 Interval & expandTo(Scalar x) {
193 if (isEmpty()) {
194 _a = x;
195 _b = x;
196 } else if (x < _a) {
197 _a = x;
198 } else if (x > _b) {
199 _b = x;
200 }
201 return *this;
202 }
203
204 Interval & expandTo(Interval const & x) {
205 if (isEmpty()) {
206 *this = x;
207 } else if (!x.isEmpty()) {
208 _a = std::min(_a, x._a);
209 _b = std::max(_b, x._b);
210 }
211 return *this;
212 }
214
218 Derived expandedTo(Scalar x) const { return Interval(*this).expandTo(x); }
219
220 Derived expandedTo(Interval const & x) const {
221 return Interval(*this).expandTo(x);
222 }
224
230 Interval & dilateBy(Scalar x) {
231 if (x == x && !isEmpty()) {
232 _a = _a - x;
233 _b = _b + x;
234 }
235 return *this;
236 }
237
238 Interval & erodeBy(Scalar x) { return dilateBy(-x); }
239 Derived dilatedBy(Scalar x) const { return Interval(*this).dilateBy(x); }
240 Derived erodedBy(Scalar x) const { return Interval(*this).erodeBy(x); }
241
242private:
243 Scalar _a;
244 Scalar _b;
245};
246
247
248template <typename Derived, typename Scalar>
250 if (isEmpty()) {
251 if (x != x) {
252 return CONTAINS | DISJOINT | WITHIN;
253 }
254 return DISJOINT | WITHIN;
255 }
256 if (x != x) {
257 return CONTAINS | DISJOINT;
258 }
259 if (_a == x && _b == x) {
260 return CONTAINS | WITHIN;
261 }
262 if (intersects(x)) {
263 return CONTAINS;
264 }
265 return DISJOINT;
266}
267
268template <typename Derived, typename Scalar>
270 Interval<Derived, Scalar> const & x) const
271{
272 if (isEmpty()) {
273 if (x.isEmpty()) {
274 return CONTAINS | DISJOINT | WITHIN;
275 }
276 return DISJOINT | WITHIN;
277 }
278 if (x.isEmpty()) {
279 return CONTAINS | DISJOINT;
280 }
281 if (_a == x._a && _b == x._b) {
282 return CONTAINS | WITHIN;
283 }
284 if (_a > x._b || _b < x._a) {
285 return DISJOINT;
286 }
287 if (_a <= x._a && _b >= x._b) {
288 return CONTAINS;
289 }
290 if (x._a <= _a && x._b >= _b) {
291 return WITHIN;
292 }
293 return INTERSECTS;
294}
295
296}} // namespace lsst::sphgeom
297
298#endif // LSST_SPHGEOM_INTERVAL_H_
Definition: Interval.h:48
Interval()
This constructor creates an empty interval.
Definition: Interval.h:51
bool isDisjointFrom(Scalar x) const
Definition: Interval.h:115
Interval(Scalar x, Scalar y)
This constructor creates an interval from the given endpoints.
Definition: Interval.h:57
bool isWithin(Scalar x) const
Definition: Interval.h:140
bool operator==(Scalar x) const
A closed interval is equal to a point x if both endpoints equal x.
Definition: Interval.h:68
Interval & dilateBy(Scalar x)
Definition: Interval.h:230
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
Derived expandedTo(Scalar x) const
Definition: Interval.h:218
Derived clippedTo(Scalar x) const
Definition: Interval.h:183
Relationship relate(Scalar x) const
Definition: Interval.h:249
bool operator==(Interval const &i) const
Definition: Interval.h:61
bool intersects(Scalar x) const
Definition: Interval.h:130
Scalar getCenter() const
Definition: Interval.h:89
Scalar getA() const
Definition: Interval.h:76
Interval & expandTo(Scalar x)
Definition: Interval.h:192
bool contains(Scalar x) const
Definition: Interval.h:98
Scalar getB() const
Definition: Interval.h:80
Interval(Scalar x)
This constructor creates a closed interval containing only x.
Definition: Interval.h:54
This file provides a type alias for describing set relationships.
std::bitset< 3 > Relationship
Relationship describes how two sets are related.
Definition: Relationship.h:35