LSSTApplications  12.1-5-gbdcc3ab+2,15.0+14,15.0+30,15.0-1-g19261fa+21,15.0-1-g417ea41,15.0-1-g60afb23+30,15.0-1-g615e0bb+22,15.0-1-g788a293+30,15.0-1-ga91101e+30,15.0-1-gae1598d+13,15.0-1-gd076f1f+28,15.0-1-gdf18595+5,15.0-12-g3681e7a+8,15.0-12-g7952b551+2,15.0-16-g6f0eb036+3,15.0-17-g076ea75+3,15.0-2-g100d730+23,15.0-2-g8aea5f4+1,15.0-2-gf38729e+25,15.0-2-gf60f3cf,15.0-3-g707930d+3,15.0-3-g9103c06+12,15.0-30-g9378914ca+1,15.0-4-g9ee0f43+3,15.0-4-gf6f1c6c+3,15.0-4-gf906033+2,15.0-5-g23e394c+18,15.0-5-g4be42a9+4,15.0-5-gae1eaf0+3,15.0-6-g09241ba+6,15.0-6-g69628aa+4,15.0-6-g81517ef+3,15.0-6-gc1213af+3,15.0-6-gfa9b38f+8,15.0-7-ged79c87+3,15.0-8-g13fca11+3,15.0-8-g67a62d3+5,15.0-8-gcf05001+5,15.0-9-g1e7c341+2,w.2018.25
LSSTDataManagementBasePackage
Extent.h
Go to the documentation of this file.
1 /*
2  * Developed for the LSST Data Management System.
3  * This product includes software developed by the LSST Project
4  * (https://www.lsst.org).
5  * See the COPYRIGHT file at the top-level directory of this distribution
6  * for details of code ownership.
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 GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 /*
23  * A coordinate class intended to represent offsets and dimensions.
24  */
25 #ifndef LSST_GEOM_EXTENT_H
26 #define LSST_GEOM_EXTENT_H
27 
28 #include <tuple>
29 #include <type_traits>
30 
31 #include "lsst/pex/exceptions.h"
33 
34 namespace lsst {
35 namespace geom {
36 
37 // These are present to avoid a static assertion for instantiating computeNorm() on integer types.
38 namespace detail {
39 
40 template <int N>
42  return s.asEigen().norm();
43 }
44 
45 template <int N>
47  throw LSST_EXCEPT(pex::exceptions::LogicError, "Cannot compute norm of integer extent");
48 #if 1 // make compilers happy in non-void function
49  return -1;
50 #endif
51 }
52 
53 } // namespace detail
54 
55 template <typename T, int N>
56 class ExtentBase : public CoordinateBase<Extent<T, N>, T, N> {
57  typedef CoordinateBase<Extent<T, N>, T, N> Super;
58 
59 public:
60  ExtentBase(ExtentBase const &) = default;
61  ExtentBase(ExtentBase &&) = default;
62  ExtentBase &operator=(ExtentBase const &) = default;
63  ExtentBase &operator=(ExtentBase &&) = default;
64  ~ExtentBase() = default;
65 
67  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
68 
70  T computeNorm() const { return detail::computeExtentNorm(static_cast<Extent<T, N> const &>(*this)); }
71 
77  bool operator==(Extent<T, N> const &other) const { return all(this->eq(other)); }
78 
84  bool operator!=(Extent<T, N> const &other) const { return any(this->ne(other)); }
85 
99  CoordinateExpr<N> eq(Extent<T, N> const &other) const;
100  CoordinateExpr<N> ne(Extent<T, N> const &other) const;
101  CoordinateExpr<N> lt(Extent<T, N> const &other) const;
102  CoordinateExpr<N> le(Extent<T, N> const &other) const;
103  CoordinateExpr<N> gt(Extent<T, N> const &other) const;
104  CoordinateExpr<N> ge(Extent<T, N> const &other) const;
105  CoordinateExpr<N> eq(T scalar) const { return this->eq(Extent<T, N>(scalar)); }
106  CoordinateExpr<N> ne(T scalar) const { return this->ne(Extent<T, N>(scalar)); }
107  CoordinateExpr<N> lt(T scalar) const { return this->lt(Extent<T, N>(scalar)); }
108  CoordinateExpr<N> le(T scalar) const { return this->le(Extent<T, N>(scalar)); }
109  CoordinateExpr<N> gt(T scalar) const { return this->gt(Extent<T, N>(scalar)); }
110  CoordinateExpr<N> ge(T scalar) const { return this->ge(Extent<T, N>(scalar)); }
112 
119  Point<T, N> operator+(Point<T, N> const &other) const;
120  Extent<T, N> operator+(Extent<T, N> const &other) const {
121  return Extent<T, N>(this->_vector + other._vector);
122  }
123  Extent<T, N> operator-(Extent<T, N> const &other) const {
124  return Extent<T, N>(this->_vector - other._vector);
125  }
127  this->_vector += other._vector;
128  return static_cast<Extent<T, N> &>(*this);
129  }
131  this->_vector -= other._vector;
132  return static_cast<Extent<T, N> &>(*this);
133  }
134  Extent<T, N> operator+() const { return static_cast<Extent<T, N> const &>(*this); }
135  Extent<T, N> operator-() const { return Extent<T, N>(-this->_vector); }
137 
144  Extent<T, N> operator*(T scalar) const { return Extent<T, N>(this->_vector * scalar); }
146  this->_vector *= scalar;
147  return static_cast<Extent<T, N> &>(*this);
148  }
149  Extent<T, N> operator/(T scalar) const { return Extent<T, N>(this->_vector / scalar); }
151  this->_vector /= scalar;
152  return static_cast<Extent<T, N> &>(*this);
153  }
155 
157  Point<T, N> asPoint() const;
158 
160  std::stringstream out;
161  out << "Extent(";
162  for (size_t i = 0; i < N; ++i) {
163  if (i != 0) {
164  out << ",";
165  }
166  out << (*this)[i];
167  }
168  out << ")";
169  return out.str();
170  }
171 
172 protected:
174  explicit ExtentBase(T val = static_cast<T>(0)) : Super(val) {}
175 
177  template <typename Vector>
178  explicit ExtentBase(Eigen::MatrixBase<Vector> const &vector) : Super(vector) {}
179 };
180 
188 template <typename T, int N>
189 class Extent : public ExtentBase<T, N> {
190  typedef ExtentBase<T, N> Super;
191 
192 public:
193  typedef typename Super::EigenVector EigenVector;
194 
196  explicit Extent(T val = static_cast<T>(0)) : Super(val) {}
197 
199  explicit Extent(EigenVector const &vector) : Super(vector) {}
200 
202  explicit Extent(Point<T, N> const &other);
203 
205  template <typename U>
206  explicit Extent(Extent<U, N> const &other);
207  template <typename U>
208  explicit Extent(Point<U, N> const &other);
209 
210  Extent(Extent const &other);
211  Extent(Extent &&other);
212  ~Extent() = default;
213 
214  Extent &operator=(Extent const &other) = default;
215  Extent &operator=(Extent &&other) = default;
216 
218  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
219 
221  T computeNorm() const { return this->asEigen().norm(); }
222 
223  void swap(Extent &other) { this->_swap(other); }
224 };
225 
231 template <typename T>
232 class Extent<T, 2> : public ExtentBase<T, 2> {
233  typedef ExtentBase<T, 2> Super;
234 
235 public:
236  typedef typename Super::EigenVector EigenVector;
237 
239  explicit Extent(T val = static_cast<T>(0)) : Super(val) {}
240 
242  explicit Extent(EigenVector const &vector) : Super(vector) {}
243 
245  explicit Extent(Point<T, 2> const &other);
246 
248  template <typename U>
249  explicit Extent(Extent<U, 2> const &other);
250  template <typename U>
251  explicit Extent(Point<U, 2> const &other);
252 
254  explicit Extent(T x, T y) : Super(EigenVector(x, y)) {}
255 
257  explicit Extent(T const xy[2]) : Super(EigenVector(xy[0], xy[1])) {}
258 
260  explicit Extent(std::pair<T, T> const &xy) : Super(EigenVector(xy.first, xy.second)) {}
261 
263  explicit Extent(std::tuple<T, T> const &xy) : Super(EigenVector(std::get<0>(xy), std::get<1>(xy))) {}
264 
265  Extent(Extent const &other);
266  Extent(Extent &&other);
267  ~Extent() = default;
268 
269  Extent &operator=(Extent const &other) = default;
270  Extent &operator=(Extent &&other) = default;
271 
272  void swap(Extent &other) { this->_swap(other); }
273 };
274 
280 template <typename T>
281 class Extent<T, 3> : public ExtentBase<T, 3> {
282  typedef ExtentBase<T, 3> Super;
283 
284 public:
285  typedef typename Super::EigenVector EigenVector;
286 
288  explicit Extent(T val = static_cast<T>(0)) : Super(val) {}
289 
291  explicit Extent(EigenVector const &vector) : Super(vector) {}
292 
294  explicit Extent(Point<T, 3> const &other);
295 
297  template <typename U>
298  explicit Extent(Extent<U, 3> const &other);
299  template <typename U>
300  explicit Extent(Point<U, 3> const &other);
301 
303  explicit Extent(T x, T y, T z) : Super(EigenVector(x, y, z)) {}
304 
306  explicit Extent(T const xyz[3]) : Super(EigenVector(xyz[0], xyz[1], xyz[2])) {}
307 
309  explicit Extent(std::tuple<T, T, T> const &xyz)
310  : Super(EigenVector(std::get<0>(xyz), std::get<1>(xyz), std::get<2>(xyz))) {}
311 
312  Extent(Extent const &other);
313  Extent(Extent &&other);
314  ~Extent() = default;
315 
316  Extent &operator=(Extent const &other) = default;
317  Extent &operator=(Extent &&other) = default;
318 
319  void swap(Extent &other) { this->_swap(other); }
320 };
321 
322 // Constructor for any 2D type from 2I type
323 template <typename T>
324 template <typename U>
327  "can only construct from Extent of different but integral type");
328  this->setX(static_cast<T>(other.getX()));
329  this->setY(static_cast<T>(other.getY()));
330 };
331 
332 // Should be consistent with converting constructor
333 template <typename T>
334 Extent<T, 2>::Extent(Extent<T, 2> const &) = default;
335 template <typename T>
336 Extent<T, 2>::Extent(Extent<T, 2> &&) = default;
337 
338 template <typename T>
339 template <typename U>
342  "can only construct from Extent of different but integral type");
343  this->setX(static_cast<T>(other.getX()));
344  this->setY(static_cast<T>(other.getY()));
345 };
346 
347 // Constructor for any 3D type from 3I type
348 template <typename T>
349 template <typename U>
352  "can only construct from Extent of different but integral type");
353  this->setX(static_cast<T>(other.getX()));
354  this->setY(static_cast<T>(other.getY()));
355  this->setZ(static_cast<T>(other.getZ()));
356 };
357 
358 // Should be consistent with converting constructor
359 template <typename T>
360 Extent<T, 3>::Extent(Extent<T, 3> const &) = default;
361 template <typename T>
362 Extent<T, 3>::Extent(Extent<T, 3> &&) = default;
363 
364 // Constructor for any 3D type from 3I type
365 template <typename T>
366 template <typename U>
369  "can only construct from Extent of different but integral type");
370  this->setX(static_cast<T>(other.getX()));
371  this->setY(static_cast<T>(other.getY()));
372  this->setZ(static_cast<T>(other.getZ()));
373 };
374 
375 typedef Extent<int, 2> ExtentI;
381 
387 template <int N>
389 
395 template <int N>
397 
403 template <int N>
405 
406 // Some operators below need to take ExtentBase arguments rather than Extent to
407 // avoid ambiguous overloads (since some competing operators are defined as member
408 // functions on ExtentBase).
409 
410 template <typename T, int N>
411 Extent<T, N> operator*(T scalar, ExtentBase<T, N> const &rhs) {
412  return rhs * scalar;
413 }
414 
415 template <int N>
417  return Extent<double, N>(static_cast<Extent<int, N> const &>(lhs)) * rhs;
418 }
419 
420 template <int N>
421 void operator*=(ExtentBase<int, N> &lhs, double rhs) {
422  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
423  static_assert(N < 0, "In-place multiplication of Extent<int,N> by double would truncate.");
424 }
425 
426 template <int N>
428  return Extent<double, N>(static_cast<Extent<int, N> const &>(lhs)) / rhs;
429 }
430 
431 template <int N>
432 void operator/=(ExtentBase<int, N> &lhs, double rhs) {
433  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
434  static_assert(N < 0, "In-place division of Extent<int,N> by double would truncate.");
435 }
436 
437 template <int N>
439  return lhs * Extent<double, N>(static_cast<Extent<int, N> const &>(rhs));
440 }
441 
442 template <int N>
444  return lhs + Extent<double, N>(rhs);
445 }
446 
447 template <int N>
449  return lhs += Extent<double, N>(rhs);
450 }
451 
452 template <int N>
454  return lhs - Extent<double, N>(rhs);
455 }
456 
457 template <int N>
459  return lhs -= Extent<double, N>(rhs);
460 }
461 
462 template <int N>
464  return Extent<double, N>(lhs) + rhs;
465 }
466 
467 template <int N>
469  return Extent<double, N>(lhs) - rhs;
470 }
471 
472 } // namespace geom
473 } // namespace lsst
474 
475 #endif
T computeSquaredNorm() const
Return the squared L2 norm of the Extent (x^2 + y^2 + ...).
Definition: Extent.h:218
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:196
A CRTP base class for coordinate objects.
Extent< T, N > & operator/=(T scalar)
Definition: Extent.h:150
Extent< double, 3 > Extent3D
Definition: Extent.h:380
Extent< T, N > & operator*=(T scalar)
Definition: Extent.h:145
Extent(T const xy[2])
Construct from a two-element array.
Definition: Extent.h:257
ExtentBase(Eigen::MatrixBase< Vector > const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:178
A coordinate class intended to represent absolute positions (2-d specialization). ...
Definition: Point.h:194
void swap(Extent &other)
Definition: Extent.h:223
A coordinate class intended to represent absolute positions (3-d specialization). ...
Definition: Point.h:247
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:458
T computeSquaredNorm() const
Return the squared L2 norm of the Extent (x^2 + y^2 + ...).
Definition: Extent.h:67
A coordinate class intended to represent absolute positions.
bool operator==(Extent< T, N > const &other) const
Standard equality comparison.
Definition: Extent.h:77
int y
Definition: SpanSet.cc:44
STL namespace.
constexpr Angle operator+(Angle a, Angle d) noexcept
Sum of two angles.
Definition: Angle.h:295
ImageT val
Definition: CR.cc:146
A coordinate class intended to represent offsets and dimensions (2-d specialization).
Definition: Extent.h:232
Extent< int, N > truncate(Extent< double, N > const &input)
Return the component-wise truncation (round towards zero).
Definition: Extent.cc:95
Extent< int, N > ceil(Extent< double, N > const &input)
Return the component-wise ceil (round towards more positive).
Definition: Extent.cc:113
Extent(T const xyz[3])
Construct from a two-element array.
Definition: Extent.h:306
Extent< T, N > operator-() const
Definition: Extent.h:135
void swap(Extent &other)
Definition: Extent.h:319
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:242
CoordinateExpr< N > ge(T scalar) const
Definition: Extent.h:110
std::string toString() const
Definition: Extent.h:159
Extent< T, N > & operator+=(Extent< T, N > const &other)
Definition: Extent.h:126
STL class.
bool operator!=(Extent< T, N > const &other) const
Standard inequality comparison.
Definition: Extent.h:84
A coordinate class intended to represent offsets and dimensions (3-d specialization).
Definition: Extent.h:281
Extent< T, N > operator+(Extent< T, N > const &other) const
Definition: Extent.h:120
T computeNorm() const
Return the L2 norm of the Extent (sqrt(x^2 + y^2 + ...)).
Definition: Extent.h:221
CoordinateExpr< N > le(T scalar) const
Definition: Extent.h:108
constexpr Angle operator-(Angle a, Angle d) noexcept
Difference of two angles.
Definition: Angle.h:301
bool all(CoordinateExpr< N > const &expr)
Return true if all elements are true.
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:239
Eigen::Matrix< int, N, 1, Eigen::DontAlign > EigenVector
A base class for image defects.
Definition: cameraGeom.dox:3
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:448
Extent< T, N > & operator-=(Extent< T, N > const &other)
Definition: Extent.h:130
Eigen::Vector3d asEigen(sphgeom::Vector3d const &vector)
Definition: sphgeomUtils.h:36
A boolean coordinate.
Extent< T, N > operator-(Extent< T, N > const &other) const
Definition: Extent.h:123
Super::EigenVector EigenVector
Definition: Extent.h:236
constexpr Angle operator*(Angle a, Angle d) noexcept
Product of two angles.
Definition: Angle.h:309
Super::EigenVector EigenVector
Definition: Extent.h:285
double computeExtentNorm(Extent< double, N > const &s)
Definition: Extent.h:41
T str(T... args)
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:199
Extent(std::pair< T, T > const &xy)
Construct from a std::pair.
Definition: Extent.h:260
Reports errors in the logical structure of the program.
Definition: Runtime.h:46
A coordinate class intended to represent offsets and dimensions.
solver_t * s
Extent< T, N > operator+() const
Definition: Extent.h:134
double x
void operator*=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:421
T computeNorm() const
Return the L2 norm of the Extent (sqrt(x^2 + y^2 + ...)).
Definition: Extent.h:70
Extent(std::tuple< T, T > const &xy)
Construct from std::tuple.
Definition: Extent.h:263
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:47
constexpr Angle operator/(Angle a, int d) noexcept
Ratio of an angle and a scalar.
Definition: Angle.h:336
Extent< int, 2 > Extent2I
Definition: Extent.h:376
Extent< int, N > floor(Extent< double, N > const &input)
Return the component-wise floor (round towards more negative).
Definition: Extent.cc:104
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:291
Extent(std::tuple< T, T, T > const &xyz)
Construct from std::tuple.
Definition: Extent.h:309
Extent(T x, T y)
Construct from two scalars.
Definition: Extent.h:254
Extent< T, N > operator/(T scalar) const
Definition: Extent.h:149
CoordinateExpr< N > eq(T scalar) const
Definition: Extent.h:105
Extent< double, 2 > ExtentD
Definition: Extent.h:378
Extent< int, 2 > ExtentI
Definition: Extent.h:373
Super::EigenVector EigenVector
Definition: Extent.h:193
ExtentBase(T val=static_cast< T >(0))
Construct an Extent<T,N> with all elements set to the same scalar value.
Definition: Extent.h:174
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:288
Extent(T x, T y, T z)
Construct from three scalars.
Definition: Extent.h:303
ItemVariant const * other
Definition: Schema.cc:55
void swap(Extent &other)
Definition: Extent.h:272
EigenVector const & asEigen() const
Return a fixed-size Eigen representation of the coordinate object.
Extent< double, 2 > Extent2D
Definition: Extent.h:379
CoordinateExpr< N > ne(T scalar) const
Definition: Extent.h:106
Extent< T, N > operator*(T scalar) const
Definition: Extent.h:144
Extent< int, 3 > Extent3I
Definition: Extent.h:377
CoordinateExpr< N > gt(T scalar) const
Definition: Extent.h:109
void operator/=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:432
bool any(CoordinateExpr< N > const &expr)
Return true if any elements are true.
double z
Definition: Match.cc:44
CoordinateExpr< N > lt(T scalar) const
Definition: Extent.h:107