LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Extent.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
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 <boost/type_traits/is_integral.hpp>
33 #include <boost/static_assert.hpp>
34 #include <boost/type_traits/is_same.hpp>
35 
36 #include "lsst/pex/exceptions.h"
38 
39 namespace lsst { namespace afw { namespace geom {
40 
41 // These are present to avoid a static assertion for instantiating computeNorm() on integer types.
42 namespace detail {
43 
44 template <int N>
46  return s.asEigen().norm();
47 }
48 
49 template <int N>
51  throw LSST_EXCEPT(
52  pex::exceptions::LogicError,
53  "Cannot compute norm of integer extent"
54  );
55 #if 1 // make compilers happy in non-void function
56  return -1;
57 #endif
58 }
59 
60 } // namespace detail
61 
62 
63 template<typename T, int N>
64 class ExtentBase : public CoordinateBase<Extent<T,N>,T,N> {
66 public:
67 
69  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
70 
72  T computeNorm() const { return detail::computeExtentNorm(static_cast<Extent<T,N> const &>(*this)); }
73 
79  bool operator==(Extent<T,N> const & other) const { return all(this->eq(other)); }
80 
86  bool operator!=(Extent<T,N> const & other) const { return any(this->ne(other)); }
87 
101  CoordinateExpr<N> eq(Extent<T,N> const & other) const;
102  CoordinateExpr<N> ne(Extent<T,N> const & other) const;
103  CoordinateExpr<N> lt(Extent<T,N> const & other) const;
104  CoordinateExpr<N> le(Extent<T,N> const & other) const;
105  CoordinateExpr<N> gt(Extent<T,N> const & other) const;
106  CoordinateExpr<N> ge(Extent<T,N> const & other) const;
107  CoordinateExpr<N> eq(T scalar) const { return this->eq(Extent<T,N>(scalar)); }
108  CoordinateExpr<N> ne(T scalar) const { return this->ne(Extent<T,N>(scalar)); }
109  CoordinateExpr<N> lt(T scalar) const { return this->lt(Extent<T,N>(scalar)); }
110  CoordinateExpr<N> le(T scalar) const { return this->le(Extent<T,N>(scalar)); }
111  CoordinateExpr<N> gt(T scalar) const { return this->gt(Extent<T,N>(scalar)); }
112  CoordinateExpr<N> ge(T scalar) const { return this->ge(Extent<T,N>(scalar)); }
114 
121  Point<T,N> operator+(Point<T,N> const & other) const;
122  Extent<T,N> operator+(Extent<T,N> const & other) const {
123  return Extent<T,N>(this->_vector + other._vector);
124  }
125  Extent<T,N> operator-(Extent<T,N> const & other) const {
126  return Extent<T,N>(this->_vector - other._vector);
127  }
128  Extent<T,N> & operator+=(Extent<T,N> const & other) {
129  this->_vector += other._vector;
130  return static_cast<Extent<T,N>&>(*this);
131  }
132  Extent<T,N> & operator-=(Extent<T,N> const & other) {
133  this->_vector -= other._vector;
134  return static_cast<Extent<T,N>&>(*this);
135  }
136  Extent<T,N> operator+() const { return static_cast<Extent<T,N> const &>(*this); }
137  Extent<T,N> operator-() const { return Extent<T,N>(-this->_vector); }
139 
146  Extent<T,N> operator*(T scalar) const { return Extent<T,N>(this->_vector * scalar); }
147  Extent<T,N> & operator*=(T scalar) { this->_vector *= scalar; return static_cast<Extent<T,N>&>(*this); }
148  Extent<T,N> operator/(T scalar) const { return Extent<T,N>(this->_vector / scalar); }
149  Extent<T,N> & operator/=(T scalar) { this->_vector /= scalar; return static_cast<Extent<T,N>&>(*this); }
151 
153  Point<T,N> asPoint() const;
154 
155  std::string toString() const {
156  std::stringstream out;
157  out << "Extent(";
158  for (size_t i = 0; i < N; ++i) {
159  if (i != 0) {
160  out << ",";
161  }
162  out << (*this)[i];
163  }
164  out << ")";
165  return out.str();
166  }
167 
168 protected:
169 
171  explicit ExtentBase(T val=static_cast<T>(0)) : Super(val) {}
172 
174  template <typename Vector>
175  explicit ExtentBase(Eigen::MatrixBase<Vector> const & vector) : Super(vector) {}
176 
177 };
178 
186 template<typename T, int N>
187 class Extent : public ExtentBase<T,N> {
189 public:
190  typedef typename Super::EigenVector EigenVector;
191 
193  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
194 
196  explicit Extent(EigenVector const & vector) : Super(vector) {}
197 
199  explicit Extent(Point<T,N> const & other);
200 
202  template<typename U>
203  explicit Extent(Extent<U,N> const & other);
204  template<typename U>
205  explicit Extent(Point<U,N> const & other);
206 
208  T computeSquaredNorm() const { return this->asEigen().squaredNorm(); }
209 
211  T computeNorm() const { return this->asEigen().norm(); }
212 
213  void swap(Extent & other) { this->_swap(other); }
214 };
215 
221 template<typename T>
222 class Extent<T,2> : public ExtentBase<T,2> {
224 public:
225  typedef typename Super::EigenVector EigenVector;
226 
228  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
229 
231  explicit Extent(EigenVector const & vector) : Super(vector) {}
232 
234  explicit Extent(Point<T,2> const & other);
235 
237  template<typename U>
238  explicit Extent(Extent<U,2> const & other);
239  template<typename U>
240  explicit Extent(Point<U,2> const & other);
241 
243  explicit Extent(T x, T y) : Super(EigenVector(x, y)) {}
244 
246  explicit Extent(T const xy[2]) : Super(EigenVector(xy[0], xy[1])) {}
247 
249  explicit Extent(std::pair<T,T> const & xy) : Super(EigenVector(xy.first, xy.second)) {}
250 
252  explicit Extent(boost::tuple<T,T> const & xy) :
253  Super(EigenVector(xy.template get<0>(), xy.template get<1>())) {}
254 
255 #ifdef SWIG
256  T getX() const;
257  T getY() const;
258  void setX(T x);
259  void setY(T y);
260 #endif
261 
262  void swap(Extent & other) { this->_swap(other); }
263 };
264 
270 template<typename T>
271 class Extent<T,3> : public ExtentBase<T,3> {
273 public:
274  typedef typename Super::EigenVector EigenVector;
275 
277  explicit Extent(T val=static_cast<T>(0)) : Super(val) {}
278 
280  explicit Extent(EigenVector const & vector) : Super(vector) {}
281 
283  explicit Extent(Point<T,3> const & other);
284 
286  template<typename U>
287  explicit Extent(Extent<U,3> const & other);
288  template<typename U>
289  explicit Extent(Point<U,3> const & other);
290 
292  explicit Extent(T x, T y, T z) : Super(EigenVector(x, y, z)) {}
293 
295  explicit Extent(T const xyz[3]) : Super(EigenVector(xyz[0], xyz[1], xyz[2])) {}
296 
298  explicit Extent(boost::tuple<T,T,T> const & xyz) :
299  Super(EigenVector(xyz.template get<0>(), xyz.template get<1>(), xyz.template get<2>())) {}
300 
301 #ifdef SWIG
302  T getX() const;
303  T getY() const;
304  T getZ() const;
305  void setX(T x);
306  void setY(T y);
307  void setZ(T z);
308 #endif
309 
310  void swap(Extent & other) { this->_swap(other); }
311 };
312 
313 // Constructor for any 2D type from 2I type
314 template<typename T>
315 template<typename U>
317 {
318  BOOST_STATIC_ASSERT( (!boost::is_same<T,U>::value && boost::is_integral<U>::value) );
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  BOOST_STATIC_ASSERT( (!boost::is_same<T,U>::value && boost::is_integral<U>::value) );
328  this->setX(static_cast<T>(other.getX()));
329  this->setY(static_cast<T>(other.getY()));
330 };
331 
332 // Constructor for any 3D type from 3I type
333 template<typename T>
334 template<typename U>
336 {
337  BOOST_STATIC_ASSERT( (!boost::is_same<T,U>::value && boost::is_integral<U>::value) );
338  this->setX(static_cast<T>(other.getX()));
339  this->setY(static_cast<T>(other.getY()));
340  this->setZ(static_cast<T>(other.getZ()));
341 };
342 
343 // Constructor for any 3D type from 3I type
344 template<typename T>
345 template<typename U>
347 {
348  BOOST_STATIC_ASSERT( (!boost::is_same<T,U>::value && boost::is_integral<U>::value) );
349  this->setX(static_cast<T>(other.getX()));
350  this->setY(static_cast<T>(other.getY()));
351  this->setZ(static_cast<T>(other.getZ()));
352 };
353 
354 typedef Extent<int,2> ExtentI;
360 
366 template <int N>
368 
374 template <int N>
375 Extent<int,N> floor(Extent<double,N> const & input);
376 
382 template <int N>
383 Extent<int,N> ceil(Extent<double,N> const & input);
384 
385 #ifndef SWIG
386 
387 // Some operators below need to take ExtentBase arguments rather than Extent to
388 // avoid ambiguous overloads (since some competing operators are defined as member
389 // functions on ExtentBase).
390 
391 template <typename T, int N>
392 Extent<T,N> operator*(T scalar, ExtentBase<T,N> const & rhs) {
393  return rhs * scalar;
394 }
395 
396 template <int N>
397 Extent<double,N> operator*(ExtentBase<int,N> const & lhs, double rhs) {
398  return Extent<double,N>(static_cast<Extent<int,N> const &>(lhs)) * rhs;
399 }
400 
401 template <int N>
402 void operator*=(ExtentBase<int,N> & lhs, double rhs) {
403  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
404  static_assert(N < 0, "In-place multiplication of Extent<int,N> by double would truncate.");
405 }
406 
407 template <int N>
408 Extent<double,N> operator/(ExtentBase<int,N> const & lhs, double rhs) {
409  return Extent<double,N>(static_cast<Extent<int,N> const &>(lhs)) / rhs;
410 }
411 
412 template <int N>
413 void operator/=(ExtentBase<int,N> & lhs, double rhs) {
414  // use "N < 0" so assertion is dependent on template instantiation, instead of triggering all the time
415  static_assert(N < 0, "In-place division of Extent<int,N> by double would truncate.");
416 }
417 
418 template <int N>
419 Extent<double,N> operator*(double lhs, ExtentBase<int,N> const & rhs) {
420  return lhs * Extent<double,N>(static_cast<Extent<int,N> const &>(rhs));
421 }
422 
423 template <int N>
425  return lhs + Extent<double,N>(rhs);
426 }
427 
428 template <int N>
430  return lhs += Extent<double,N>(rhs);
431 }
432 
433 template <int N>
435  return lhs - Extent<double,N>(rhs);
436 }
437 
438 template <int N>
440  return lhs -= Extent<double,N>(rhs);
441 }
442 
443 template <int N>
445  return Extent<double,N>(lhs) + rhs;
446 }
447 
448 template <int N>
450  return Extent<double,N>(lhs) - rhs;
451 }
452 
453 #endif // !SWIG
454 
455 }}}
456 
457 #endif
Extent< T, N > operator/(T scalar) const
Definition: Extent.h:148
int y
Extent< int, N > truncate(Extent< double, N > const &input)
Extent< double, 3 > Extent3D
Definition: Extent.h:359
A boolean coordinate.
Extent(std::pair< T, T > const &xy)
Construct from a std::pair.
Definition: Extent.h:249
const Angle operator/(Angle const a, int d)
Definition: Angle.h:274
A coordinate class intended to represent absolute positions (2-d specialization). ...
Definition: Point.h:183
Extent(T x, T y)
Construct from two scalars.
Definition: Extent.h:243
Extent(boost::tuple< T, T, T > const &xyz)
Construct from boost::tuple.
Definition: Extent.h:298
void swap(Extent &other)
Definition: Extent.h:310
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:277
ExtentBase< T, N > Super
Definition: Extent.h:188
Extent(boost::tuple< T, T > const &xy)
Construct from boost::tuple.
Definition: Extent.h:252
bool all(CoordinateExpr< N > const &expr)
Return true if all elements are true.
CoordinateExpr< N > gt(T scalar) const
Definition: Extent.h:111
Extent(T const xy[2])
Construct from a two-element array.
Definition: Extent.h:246
Super::EigenVector EigenVector
Definition: Extent.h:225
ExtentBase< T, 3 > Super
Definition: Extent.h:272
CoordinateBase< Extent< T, N >, T, N > Super
Definition: Extent.h:65
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:280
void operator/=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:413
Include files required for standard LSST Exception handling.
A coordinate class intended to represent offsets and dimensions.
Extent< T, N > & operator*=(T scalar)
Definition: Extent.h:147
Extent(T const xyz[3])
Construct from a two-element array.
Definition: Extent.h:295
Extent< T, N > & operator/=(T scalar)
Definition: Extent.h:149
Super::EigenVector EigenVector
Definition: Extent.h:274
Extent< double, N > & operator+=(Extent< double, N > &lhs, Extent< int, N > const &rhs)
Definition: Extent.h:429
Extent< T, N > operator*(T scalar) const
Definition: Extent.h:146
void swap(Extent &other)
Definition: Extent.h:213
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:439
CoordinateExpr< N > gt(Extent< T, N > const &other) const
Eigen::Matrix< T, N, 1, Eigen::DontAlign > EigenVector
Extent< int, 2 > Extent2I
Definition: Extent.h:355
Extent< int, N > ceil(Extent< double, N > const &input)
bool operator!=(Extent< T, N > const &other) const
Standard inequality comparison.
Definition: Extent.h:86
Extent< T, N > operator-(Extent< T, N > const &other) const
Definition: Extent.h:125
A CRTP base class for coordinate objects.
A coordinate class intended to represent absolute positions.
bool val
const Angle operator+(Angle const a, Angle const d)
Definition: Angle.h:264
Extent< double, 2 > ExtentD
Definition: Extent.h:357
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:128
ExtentBase< T, 2 > Super
Definition: Extent.h:223
const Angle operator*(Angle const a, Angle const d)
Definition: Angle.h:266
void operator*=(ExtentBase< int, N > &lhs, double rhs)
Definition: Extent.h:402
T computeSquaredNorm() const
Return the squared L2 norm of the Extent (x^2 + y^2 + ...).
Definition: Extent.h:69
Extent< T, N > operator-() const
Definition: Extent.h:137
Extent< T, N > operator+(Extent< T, N > const &other) const
Definition: Extent.h:122
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:208
double x
double computeExtentNorm(Extent< double, N > const &s)
Definition: Extent.h:45
T computeNorm() const
Return the L2 norm of the Extent (sqrt(x^2 + y^2 + ...)).
Definition: Extent.h:72
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:231
std::string toString() const
Definition: Extent.h:155
CoordinateExpr< N > ge(T scalar) const
Definition: Extent.h:112
Extent< int, 3 > Extent3I
Definition: Extent.h:356
Extent< int, 2 > ExtentI
Definition: Extent.h:352
Extent< T, N > operator+() const
Definition: Extent.h:136
bool operator==(Extent< T, N > const &other) const
Standard equality comparison.
Definition: Extent.h:79
ExtentBase(Eigen::MatrixBase< Vector > const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:175
#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:107
Extent< int, N > floor(Extent< double, N > const &input)
Super::EigenVector EigenVector
Definition: Extent.h:190
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:108
Extent(T x, T y, T z)
Construct from three scalars.
Definition: Extent.h:292
CoordinateExpr< N > ge(Extent< T, N > const &other) const
CoordinateExpr< N > lt(T scalar) const
Definition: Extent.h:109
CoordinateExpr< N > le(T scalar) const
Definition: Extent.h:110
Extent< double, 2 > Extent2D
Definition: Extent.h:358
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:211
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:171
Extent(T val=static_cast< T >(0))
Construct an Extent with all elements set to the same scalar value.
Definition: Extent.h:193
void swap(Extent &other)
Definition: Extent.h:262
const Angle operator-(Angle const a, Angle const d)
Definition: Angle.h:265
Extent(EigenVector const &vector)
Construct an Extent from an Eigen vector.
Definition: Extent.h:196
Extent< T, N > & operator-=(Extent< T, N > const &other)
Definition: Extent.h:132
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:228
A coordinate class intended to represent absolute positions (3-d specialization). ...
Definition: Point.h:236