iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Dims.H
Go to the documentation of this file.
1 /*! @file
2  @author Randolph Voorhies
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_GEOMETRY_DIMS_H
37 #define INCLUDE_NRT_CORE_GEOMETRY_DIMS_H
38 
41 #include <nrt/External/cereal/cereal.hpp>
42 #include <iosfwd>
43 
44 /*! \defgroup geometry Geometry-related classes and functions
45 
46  Includes simple classes for points, rectangles, dimensions, lines, circles, etc.
47 
48  The geometry classes are meant to be simple and efficient yet provide sufficient versatility. Most classes support
49  the following:
50 
51  - template typing, so that the geometric primitives can be instantiated for int, float, double, or many other
52  underlying base types. Not all features may work for any underlying base type, depending on what that type
53  supports (e.g., addition of geometry types requires that addition be defined for the underlying base type).
54 
55  - explicit constructors, which eliminates the risks associated with implicit conversion and construction. This
56  also means that one must be explicit when converting between geometric primitives that use different underlying
57  base types. For example:
58  @code
59  nrt::Point2D<int> p(100, 100);
60  nrt::Point2D<float> pp(p); // ok, explicit construction of pp from p
61  //pp = p; // does not compile: implicit conversion not allowed in assignment
62  pp = nrt::Point2D<float>(p); // ok, explicit conversion
63  @endcode
64  Note that clamping and rounding may occur when converting, based on the behavior of nrt::clamped_convert which is
65  used internally by converting geometry constructors, for example:
66  @code
67  nrt::Point2D<float> pfl(12.34F, 567.89F);
68  nrt::Point2D<int> pin(pfl); // pin is (12, 568)
69  nrt::Point2D<nrt::byte> pby(pfl); // pby is (12, 255)
70  @endcode
71  Finally note that rounding is based on the C++11 std::round() function, which correctly handles both positive and
72  negative numbers (see \link test-Point.C \endlink for examples).
73 
74  - copy and move constructors and assignment so that it is inexpensive to return geometric primitives from functions.
75 
76  - operator overloads where they make sense:
77  - All geometric primitives support equality and inequality operators.
78  - Most geometric primitives multiplication and division by a double-precision scalar, which scales all coordinates
79  in the primitive.
80  - Many geometric primitives support a free function \c nrt::scale(), which differs from multiplication in that it
81  will scale the size of the object without changing its position, while multiplication scales all coordinates (so
82  multiplication is appropriate for, e.g., resolution changes while \c scale() is for growing/shrinking an object
83  without moving it).
84  - Many geometric primitives support a free function \c nrt::rotate() which rotates the primitive about its
85  canonical center.
86  - Most geometric primitives support an \c area() function that returns the area as a double-precision number.
87  - Many geometric primitives support addition and subtraction with a Point2D of same template parameter, which
88  corresponds to translation.
89  - Some geometric primitives support addition and subtraction with another object of their own (e.g., Dims<int> +
90  Dims<int>) but usually product and division of that kind is not supported as it makes little sense.
91 
92  - read-only access member functions, to fetch elements out of the geometric primitives (e.g., get the center
93  coordinates and the radius of a Circle). No write member functions are provided, instead you should create a new
94  geometric primitive. For example:
95  @code
96  nrt::Circle<int> circle(nrt::Point2D<int>(100, 100), 10); // center at (100,100), radius 10
97  int radius = circle.radius(); // ok
98  nrt::point2D<int> center = circle.center(); // ok
99  // We create a new circle instead of trying to modify our existing one:
100  nrt::Circle<int> newcircle(circle.center() + nrt::Point2D<int>(20, 30),
101  circle.radius() + 5); // center at (120,130), radius 15
102  @endcode
103 
104  - a contains(Point2D<U> point) function which returns true if a point is inside the geometric primitive (for Circle,
105  Rectangle, Dims, etc). Any point is ok for this function.
106 
107  Many examples of use are provided in \link test-Geometry.C \endlink, \link test-Point.C \endlink and other example
108  files.
109 
110  \ingroup core */
111 
112 namespace nrt
113 {
114  //! A generic dimensions class
115  /*! The Dims class is used to represent the size of a 2-dimensional object, for example an Image.
116  \tparam T The internal datatype with which to store the width and height. The majority of nrt uses int32.
117 
118  \note The operators of Dims do not use type promotions (see \ref promotions). This is to minimize template burden
119  and also possible programmer confusion. For example, while in principle one could define Dims<int> + float and
120  return a Dims<float>, here we do not define such an operator. The same result can be achieved by first converting
121  the range and then adding the constant:
122  @code
123  nrt::Dims<int> r1(100, 100);
124  // NOT ALLOWED: nrt::Dims<float> r2 = r1 + 1.23F;
125  nrt::Dims<float> r2 = nrt::Dims<float>(r1) + 1.23F; // OK, no hidden conversions, easy to read, explicit, nice
126  @endcode
127 
128  \note Operators on Dims use range checking and clamping internally. Thus, be careful if using Dims<byte>. For
129  example:
130  @code
131  nrt::Dims<nrt::byte> d(nrt::byte(3), nrt::byte(250));
132  d += nrt::byte(250); // new dims is 253x255
133  @endcode
134 
135  \todo The multiplication operators seem to not work properly.
136 
137  \ingroup geometry */
138  template <class T>
139  class Dims
140  {
141  public:
142  //! Default constructor - creates a Dims with width and height = 0
143  explicit Dims();
144 
145  //! Construct with from a given width and height
146  explicit Dims(T const width, T const height);
147 
148  //! Copy constructor
149  Dims(Dims<T> const & other) = default;
150 
151  //! Move constructor
152  Dims(Dims<T> && other) = default;
153 
154  //! Copy-conversion constructor, uses nrt::clamped_convert<T,U> internally
155  template <class U>
156  explicit Dims(Dims<U> const & other);
157 
158  //! Assignment
159  Dims<T> & operator=(Dims<T> const & other) = default;
160 
161  //! Move assignment
162  Dims<T> & operator=(Dims<T> && other) = default;
163 
164  //! Return the width
165  T width() const;
166 
167  //! Return the height
168  T height() const;
169 
170  //! Return the size (width * height)
171  T size() const;
172 
173  //! Return whether the Dims encloses 0 area
174  bool empty() const;
175 
176  //! Return whether the given point is contained in this Dims
177  /*! This is equivalent to asking whether a Rectangle with its top-left corner at (0,0) and dimensions equal to
178  this class contains the point. */
179  template <class U>
180  bool contains(Point2D<U> const & p) const;
181 
182  //! Serialize Dims into an Archive
183  template <class Archive> void serialize(Archive & ar)
184  {
185  ar( itsWidth, itsHeight );
186  }
187  friend class cereal::access;
188 
189  private:
190  T itsWidth; //!< The width dimension
191  T itsHeight; //!< The height dimension
192  };
193 
194  // ######################################################################
195  // Free functions for Dims<T>
196  // ######################################################################
197 
198  //! Human-readable output to a stream: outputs \c width x \c height (with no space, e.g., 640x480)
199  /*! \relates Dims */
200  template <class T>
201  std::ostream & operator<<(std::ostream & out, Dims<T> const & d);
202 
203  //! Human-readable input from a stream: reads \c width x \c height (with no space, e.g., 640x480)
204  /*! @throws nrt::exception::Exception if input is malformed
205  \relates Dims */
206  template <class T>
207  std::istream & operator>>(std::istream & in, Dims<T> & d);
208 
209  //! Machine-readable output to a string, for use in nrt::Parameter: outputs \c width x \c height (e.g., 640x480)
210  /*! This is an overload for Dims<T> of the function template in nrt/Core/Model/ParameterStringConversion.H.
211  \relates Dims */
212  template <class T>
213  void paramValToString(Dims<T> const & val, std::string & result);
214 
215  //! Machine-readable input from a string, for use in nrt::Parameter: reads \c width x \c height (e.g., 640x480)
216  /*! @throws nrt::exception::Exception if input is malformed.
217  This is an overload for Dims<T> of the function template in nrt/Core/Model/ParameterStringConversion.H.
218  \relates Dims */
219  template <class T>
220  void paramStringToVal(std::string const & valstring, Dims<T> & result);
221 
222  //! Operator overload for Dims<T> == Dims<T>
223  /*! \relates Dims */
224  template <class T>
225  bool operator==(Dims<T> const & dims1, Dims<T> const & dims2);
226 
227  //! Operator overload for Dims<T> != Dims<T>
228  /*! \relates Dims */
229  template <class T>
230  bool operator!=(Dims<T> const & dims1, Dims<T> const & dims2);
231 
232  //! Operator overload for Dims<T> + Dims<T>
233  /*! \relates Dims */
234  template <class T>
235  Dims<T> operator+(Dims<T> const & dims1, Dims<T> const & dims2);
236 
237  //! Operator overload for Dims<T> + T
238  /*! \relates Dims */
239  template <class T>
240  Dims<T> operator+(Dims<T> const & dims, T const scalar);
241 
242  //! Operator overload for T + Dims<T>
243  /*! \relates Dims */
244  template <class T>
245  Dims<T> operator+(T const scalar, Dims<T> const & dims);
246 
247  //! Operator overload for Dims<T> - Dims<T>
248  /*! \relates Dims */
249  template <class T>
250  Dims<T> operator-(Dims<T> const & dims1, Dims<T> const & dims2);
251 
252  //! Operator overload for Dims<T> - T
253  /*! \relates Dims */
254  template <class T>
255  Dims<T> operator-(Dims<T> const & dims, T const scalar);
256 
257  //! Operator overload for T - Dims<T>
258  /*! \relates Dims */
259  template <class T>
260  Dims<T> operator-(T const scalar, Dims<T> const & dims);
261 
262  //! Operator overload for Dims<T> / Dims<T>
263  /*! \relates Dims */
264  template <class T>
265  Dims<T> operator/(Dims<T> const & dims1, Dims<T> const & dims2);
266 
267  //! Operator overload for Dims<T> / double
268  /*! \relates Dims */
269  template <class T>
270  Dims<T> operator/(Dims<T> const & dims, double const scalar);
271 
272  //! Operator overload for Dims<T> * double
273  /*! \relates Dims */
274  template <class T>
275  Dims<T> operator*(Dims<T> const & dims, double const scalar);
276 
277  //! Operator overload for double * Dims<T>
278  /*! \relates Dims */
279  template <class T>
280  Dims<T> operator*(double const scalar, Dims<T> const & dims);
281 
282  //! Operator overload for Dims<T> += T
283  /*! \relates Dims */
284  template <class T>
285  Dims<T> & operator+=(Dims<T> & dims, T const scalar);
286 
287  //! Operator overload for Dims<T> -= T
288  /*! \relates Dims */
289  template <class T>
290  Dims<T> & operator-=(Dims<T> & dims, T const scalar);
291 
292  //! Operator overload for Dims<T> *= double
293  /*! \relates Dims */
294  template <class T>
295  Dims<T> & operator*=(Dims<T> & dims, double const scalar);
296 
297  //! Operator overload for Dims<T> /= double
298  /*! \relates Dims */
299  template <class T>
300  Dims<T> & operator/=(Dims<T> & dims, double const scalar);
301 
302  //! Operator overload for Dims<T> += Dims<T>
303  /*! \relates Dims */
304  template <class T>
305  Dims<T> & operator+=(Dims<T> & dims1, Dims<T> const & dims2);
306 
307  //! Operator overload for Dims<T> -= Dims<T>
308  /*! \relates Dims */
309  template <class T>
310  Dims<T> & operator-=(Dims<T> & dims1, Dims<T> const & dims2);
311 
312 } // namespace nrt
313 
314 // Include implementation details that are of no interest to the end user
316 
317 #endif // INCLUDE_NRT_CORE_GEOMETRY_DIMS_H
318