LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
Extent.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008-2016 AURA/LSST.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
29 #ifndef LSST_AFW_GEOM_EXTENT_H
30 #define LSST_AFW_GEOM_EXTENT_H
31 
32 #include <tuple>
33 #include <type_traits>
34 
35 #include "lsst/pex/exceptions.h"
37 
38 namespace lsst { namespace afw { namespace geom {
39 
40 // These are present to avoid a static assertion for instantiating computeNorm() on integer types.
41 namespace detail {
42 
43 template <int N>
45  return s.asEigen().norm();
46 }
47 
48 template <int N>
50  throw LSST_EXCEPT(
51  pex::exceptions::LogicError,
52  "Cannot compute norm of integer extent"
53  );
54 #if 1 // make compilers happy in non-void function
55  return -1;
56 #endif
57 }
58 
59 } // namespace detail
60 
61 
62 template<typename T, int N>
63 class ExtentBase : public CoordinateBase<Extent<T,N>,T,N> {
65 public:
66 
68  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
69 
71  T computeNorm() const { return detail::computeExtentNorm(static_cast<Extent<T,N> const &>(*this)); }
72 
78  bool operator==(Extent<T,N> const & other) const { return all(this->eq(other)); }
79 
85  bool operator!=(Extent<T,N> const & other) const { return any(this->ne(other)); }
86 
100  CoordinateExpr<N> eq(Extent<T,N> const & other) const;
101  CoordinateExpr<N> ne(Extent<T,N> const & other) const;
102  CoordinateExpr<N> lt(Extent<T,N> const & other) const;
103  CoordinateExpr<N> le(Extent<T,N> const & other) const;
104  CoordinateExpr<N> gt(Extent<T,N> const & other) const;
105  CoordinateExpr<N> ge(Extent<T,N> const & other) const;
106  CoordinateExpr<N> eq(T scalar) const { return this->eq(Extent<T,N>(scalar)); }
107  CoordinateExpr<N> ne(T scalar) const { return this->ne(Extent<T,N>(scalar)); }
108  CoordinateExpr<N> lt(T scalar) const { return this->lt(Extent<T,N>(scalar)); }
109  CoordinateExpr<N> le(T scalar) const { return this->le(Extent<T,N>(scalar)); }
110  CoordinateExpr<N> gt(T scalar) const { return this->gt(Extent<T,N>(scalar)); }
111  CoordinateExpr<N> ge(T scalar) const { return this->ge(Extent<T,N>(scalar)); }
113 
120  Point<T,N> operator+(Point<T,N> const & other) const;
121  Extent<T,N> operator+(Extent<T,N> const & other) const {
122  return Extent<T,N>(this->_vector + other._vector);
123  }
124  Extent<T,N> operator-(Extent<T,N> const & other) const {
125  return Extent<T,N>(this->_vector - other._vector);
126  }
127  Extent<T,N> & operator+=(Extent<T,N> const & other) {
128  this->_vector += other._vector;
129  return static_cast<Extent<T,N>&>(*this);
130  }
131  Extent<T,N> & operator-=(Extent<T,N> const & other) {
132  this->_vector -= other._vector;
133  return static_cast<Extent<T,N>&>(*this);
134  }
135  Extent<T,N> operator+() const { return static_cast<Extent<T,N> const &>(*this); }
136  Extent<T,N> operator-() const { return Extent<T,N>(-this->_vector); }
138 
145  Extent<T,N> operator*(T scalar) const { return Extent<T,N>(this->_vector * scalar); }
146  Extent<T,N> & operator*=(T scalar) { this->_vector *= scalar; return static_cast<Extent<T,N>&>(*this); }
147  Extent<T,N> operator/(T scalar) const { return Extent<T,N>(this->_vector / scalar); }
148  Extent<T,N> & operator/=(T scalar) { this->_vector /= scalar; return static_cast<Extent<T,N>&>(*this); }
150 
152  Point<T,N> asPoint() const;
153 
154  std::string toString() const {
155  std::stringstream out;
156  out << "Extent(";
157  for (size_t i = 0; i < N; ++i) {
158  if (i != 0) {
159  out << ",";
160  }
161  out << (*this)[i];
162  }
163  out << ")";
164  return out.str();
165  }
166 
167 protected:
168 
170  explicit ExtentBase(T val=static_cast<T>(0)) : Super(val) {}
171 
173  template <typename Vector>
174  explicit ExtentBase(Eigen::MatrixBase<Vector> const & vector) : Super(vector) {}
175 
176 };
177 
185 template<typename T, int N>
186 class Extent : public ExtentBase<T,N> {
188 public:
189  typedef typename Super::EigenVector EigenVector;
190 
192  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
193 
195  explicit Extent(EigenVector const & vector) : Super(vector) {}
196 
198  explicit Extent(Point<T,N> const & other);
199 
201  template<typename U>
202  explicit Extent(Extent<U,N> const & other);
203  template<typename U>
204  explicit Extent(Point<U,N> const & other);
205 
207  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
208 
210  T computeNorm() const { return this->asEigen().norm(); }
211 
212  void swap(Extent & other) { this->_swap(other); }
213 };
214 
220 template<typename T>
221 class Extent<T,2> : public ExtentBase<T,2> {
223 public:
224  typedef typename Super::EigenVector EigenVector;
225 
227  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
228 
230  explicit Extent(EigenVector const & vector) : Super(vector) {}
231 
233  explicit Extent(Point<T,2> const & other);
234 
236  template<typename U>
237  explicit Extent(Extent<U,2> const & other);
238  template<typename U>
239  explicit Extent(Point<U,2> const & other);
240 
242  explicit Extent(T x, T y) : Super(EigenVector(x, y)) {}
243 
245  explicit Extent(T const xy[2]) : Super(EigenVector(xy[0], xy[1])) {}
246 
248  explicit Extent(std::pair<T,T> const & xy) : Super(EigenVector(xy.first, xy.second)) {}
249 
251  explicit Extent(std::tuple<T,T> const & xy) :
252  Super(EigenVector(std::get<0>(xy), std::get<1>(xy))) {}
253 
254 #ifdef SWIG
255  T getX() const;
256  T getY() const;
257  void setX(T x);
258  void setY(T y);
259 #endif
260 
261  void swap(Extent & other) { this->_swap(other); }
262 };
263 
269 template<typename T>
270 class Extent<T,3> : public ExtentBase<T,3> {
272 public:
273  typedef typename Super::EigenVector EigenVector;
274 
276  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
277 
279  explicit Extent(EigenVector const & vector) : Super(vector) {}
280 
282  explicit Extent(Point<T,3> const & other);
283 
285  template<typename U>
286  explicit Extent(Extent<U,3> const & other);
287  template<typename U>
288  explicit Extent(Point<U,3> const & other);
289 
291  explicit Extent(T x, T y, T z) : Super(EigenVector(x, y, z)) {}
292 
294  explicit Extent(T const xyz[3]) : Super(EigenVector(xyz[0], xyz[1], xyz[2])) {}
295 
297  explicit Extent(std::tuple<T,T,T> const & xyz) :
298  Super(EigenVector(std::get<0>(xyz), std::get<1>(xyz), std::get<2>(xyz))) {}
299 
300 #ifdef SWIG
301  T getX() const;
302  T getY() const;
303  T getZ() const;
304  void setX(T x);
305  void setY(T y);
306  void setZ(T z);
307 #endif
308 
309  void swap(Extent & other) { this->_swap(other); }
310 };
311 
312 // Constructor for any 2D type from 2I type
313 template<typename T>
314 template<typename U>
316 {
317  static_assert((!std::is_same<T,U>::value && std::is_integral<U>::value),
318  "can only construct from Extent of different but integral type");
319  this->setX(static_cast<T>(other.getX()));
320  this->setY(static_cast<T>(other.getY()));
321 };
322 
323 template<typename T>
324 template<typename U>
326 {
327  static_assert((!std::is_same<T,U>::value && std::is_integral<U>::value),
328  "can only construct from Extent of different but integral type");
329  this->setX(static_cast<T>(other.getX()));
330  this->setY(static_cast<T>(other.getY()));
331 };
332 
333 // Constructor for any 3D type from 3I type
334 template<typename T>
335 template<typename U>
337 {
338  static_assert((!std::is_same<T,U>::value && std::is_integral<U>::value),
339  "can only construct from Extent of different but integral type");
340  this->setX(static_cast<T>(other.getX()));
341  this->setY(static_cast<T>(other.getY()));
342  this->setZ(static_cast<T>(other.getZ()));
343 };
344 
345 // Constructor for any 3D type from 3I type
346 template<typename T>
347 template<typename U>
349 {
350  static_assert((!std::is_same<T,U>::value && std::is_integral<U>::value),
351  "can only construct from Extent of different but integral type");
352  this->setX(static_cast<T>(other.getX()));
353  this->setY(static_cast<T>(other.getY()));
354  this->setZ(static_cast<T>(other.getZ()));
355 };
356 
357 typedef Extent<int,2> ExtentI;
363 
369 template <int N>
371 
377 template <int N>
378 Extent<int,N> floor(Extent<double,N> const & input);
379 
385 template <int N>
386 Extent<int,N> ceil(Extent<double,N> const & input);
387 
388 #ifndef SWIG
389 
390 // Some operators below need to take ExtentBase arguments rather than Extent to
391 // avoid ambiguous overloads (since some competing operators are defined as member
392 // functions on ExtentBase).
393 
394 template <typename T, int N>
395 Extent<T,N> operator*(T scalar, ExtentBase<T,N> const & rhs) {
396  return rhs * scalar;
397 }
398 
399 template <int N>
400 Extent<double,N> operator*(ExtentBase<int,N> const & lhs, double rhs) {
401  return Extent<double,N>(static_cast<Extent<int,N> const &>(lhs)) * rhs;
402 }
403 
404 template <int N>
405 void operator*=(ExtentBase<int,N> & lhs, double rhs) {
406  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
407  static_assert(N < 0, "In-place multiplication of Extent<int,N> by double would truncate.");
408 }
409 
410 template <int N>
411 Extent<double,N> operator/(ExtentBase<int,N> const & lhs, double rhs) {
412  return Extent<double,N>(static_cast<Extent<int,N> const &>(lhs)) / rhs;
413 }
414 
415 template <int N>
416 void operator/=(ExtentBase<int,N> & lhs, double rhs) {
417  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
418  static_assert(N < 0, "In-place division of Extent<int,N> by double would truncate.");
419 }
420 
421 template <int N>
422 Extent<double,N> operator*(double lhs, ExtentBase<int,N> const & rhs) {
423  return lhs * Extent<double,N>(static_cast<Extent<int,N> const &>(rhs));
424 }
425 
426 template <int N>
428  return lhs + Extent<double,N>(rhs);
429 }
430 
431 template <int N>
433  return lhs += Extent<double,N>(rhs);
434 }
435 
436 template <int N>
438  return lhs - Extent<double,N>(rhs);
439 }
440 
441 template <int N>
443  return lhs -= Extent<double,N>(rhs);
444 }
445 
446 template <int N>
448  return Extent<double,N>(lhs) + rhs;
449 }
450 
451 template <int N>
453  return Extent<double,N>(lhs) - rhs;
454 }
455 
456 #endif // !SWIG
457 
458 }}}
459 
460 #endif
Extent< T, N > operator/(T scalar) const
Definition: Extent.h:147
int y
Extent< int, N > truncate(Extent< double, N > const &input)
Extent< double, 3 > Extent3D
Definition: Extent.h:362
A boolean coordinate.
Extent(std::tuple< T, T > const &xy)
Construct from std::tuple.
Definition: Extent.h:251
Extent(std::pair< T, T > const &xy)
Construct from a std::pair.
Definition: Extent.h:248
const Angle operator/(Angle const a, int d)
Definition: Angle.h:273
A coordinate class intended to represent absolute positions (2-d specialization). ...
Definition: Point.h:185
Extent(T x, T y)
Construct from two scalars.
Definition: Extent.h:242
void swap(Extent &other)
Definition: Extent.h:309
dictionary Extent
Definition: __init__.py:40
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:276
ExtentBase< T, N > Super
Definition: Extent.h:187
bool all(CoordinateExpr< N > const &expr)
Return true if all elements are true.
CoordinateExpr< N > gt(T scalar) const
Definition: Extent.h:110
Extent(T const xy[2])
Construct from a two-element array.
Definition: Extent.h:245
Super::EigenVector EigenVector
Definition: Extent.h:224
ExtentBase< T, 3 > Super
Definition: Extent.h:271
CoordinateBase< Extent< T, N >, T, N > Super
Definition: Extent.h:64
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:279
Extent(std::tuple< T, T, T > const &xyz)
Construct from std::tuple.
Definition: Extent.h:297
void operator/=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:416
A coordinate class intended to represent offsets and dimensions.
Extent< T, N > & operator*=(T scalar)
Definition: Extent.h:146
Extent(T const xyz[3])
Construct from a two-element array.
Definition: Extent.h:294
Extent< T, N > & operator/=(T scalar)
Definition: Extent.h:148
Super::EigenVector EigenVector
Definition: Extent.h:273
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:432
Extent< T, N > operator*(T scalar) const
Definition: Extent.h:145
void swap(Extent &other)
Definition: Extent.h:212
A boolean pair class used to express the output of spatial predicates on Point and Extent...
Extent< double, N > & operator-=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:442
CoordinateExpr< N > gt(Extent< T, N > const &other) const
Eigen::Matrix< T, N, 1, Eigen::DontAlign > EigenVector
Extent< int, 2 > Extent2I
Definition: Extent.h:358
Extent< int, N > ceil(Extent< double, N > const &input)
bool operator!=(Extent< T, N > const &other) const
Standard inequality comparison.
Definition: Extent.h:85
Extent< T, N > operator-(Extent< T, N > const &other) const
Definition: Extent.h:124
A CRTP base class for coordinate objects.
A coordinate class intended to represent absolute positions.
Definition: PSF.h:39
bool val
const Angle operator+(Angle const a, Angle const d)
Definition: Angle.h:263
Extent< double, 2 > ExtentD
Definition: Extent.h:360
bool any(CoordinateExpr< N > const &expr)
Return true if any elements are true.
Extent< T, N > & operator+=(Extent< T, N > const &other)
Definition: Extent.h:127
ExtentBase< T, 2 > Super
Definition: Extent.h:222
const Angle operator*(Angle const a, Angle const d)
Definition: Angle.h:265
void operator*=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:405
T computeSquaredNorm() const
Return the squared L2 norm of the Extent (x^2 + y^2 + ...).
Definition: Extent.h:68
Extent< T, N > operator-() const
Definition: Extent.h:136
Extent< T, N > operator+(Extent< T, N > const &other) const
Definition: Extent.h:121
CoordinateExpr< N > lt(Extent< T, N > const &other) const
T computeSquaredNorm() const
Return the squared L2 norm of the Extent (x^2 + y^2 + ...).
Definition: Extent.h:207
double x
double computeExtentNorm(Extent< double, N > const &s)
Definition: Extent.h:44
T computeNorm() const
Return the L2 norm of the Extent (sqrt(x^2 + y^2 + ...)).
Definition: Extent.h:71
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:230
std::string toString() const
Definition: Extent.h:154
CoordinateExpr< N > ge(T scalar) const
Definition: Extent.h:111
Extent< int, 3 > Extent3I
Definition: Extent.h:359
Extent< int, 2 > ExtentI
Definition: Extent.h:355
Extent< T, N > operator+() const
Definition: Extent.h:135
bool operator==(Extent< T, N > const &other) const
Standard equality comparison.
Definition: Extent.h:78
ExtentBase(Eigen::MatrixBase< Vector > const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:174
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
Point< T, N > asPoint() const
Cast this object to an Extent of the same numeric type and dimensionality.
CoordinateExpr< N > eq(T scalar) const
Definition: Extent.h:106
Extent< int, N > floor(Extent< double, N > const &input)
Super::EigenVector EigenVector
Definition: Extent.h:189
CoordinateExpr< N > le(Extent< T, N > const &other) const
EigenVector const & asEigen() const
Return a fixed-size Eigen representation of the coordinate object.
CoordinateExpr< N > ne(T scalar) const
Definition: Extent.h:107
Extent(T x, T y, T z)
Construct from three scalars.
Definition: Extent.h:291
CoordinateExpr< N > ge(Extent< T, N > const &other) const
CoordinateExpr< N > lt(T scalar) const
Definition: Extent.h:108
CoordinateExpr< N > le(T scalar) const
Definition: Extent.h:109
Extent< double, 2 > Extent2D
Definition: Extent.h:361
CoordinateExpr< N > eq(Extent< T, N > const &other) const
T computeNorm() const
Return the L2 norm of the Extent (sqrt(x^2 + y^2 + ...)).
Definition: Extent.h:210
ExtentBase(T val=static_cast< T >(0))
Construct an Extent&lt;T,N&gt; with all elements set to the same scalar value.
Definition: Extent.h:170
Include files required for standard LSST Exception handling.
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:192
void swap(Extent &other)
Definition: Extent.h:261
const Angle operator-(Angle const a, Angle const d)
Definition: Angle.h:264
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:195
Extent< T, N > & operator-=(Extent< T, N > const &other)
Definition: Extent.h:131
CoordinateExpr< N > ne(Extent< T, N > const &other) const
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:227
A coordinate class intended to represent absolute positions (3-d specialization). ...
Definition: Point.h:238