iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Line.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_LINE_H
37 #define INCLUDE_NRT_CORE_GEOMETRY_LINE_H
38 
41 #include <nrt/External/cereal/cereal.hpp>
42 
43 namespace nrt
44 {
45  //! A 2D line segment
46  /*! \ingroup geometry */
47  template <class T>
48  class Line
49  {
50  public:
51  //! Default constructor - creates a Line with both ends at (0,0)
52  explicit Line();
53 
54  //! Construct a Line from the two given points
55  explicit Line(Point2D<T> const & p1, Point2D<T> const & p2);
56 
57  //! Construct a Line from the given x and y coordinates
58  explicit Line(T x1, T y1, T x2, T y2);
59 
60  //! Construct a Line from a center, ori and len
61  explicit Line(Point2D<T> const & center, double const ori, double const len);
62 
63  //! Copy constructor
64  Line(Line<T> const & other) = default;
65 
66  //! Move constructor
67  Line(Line<T> && other) = default;
68 
69  //! Copy-conversion constructor
70  template <class U>
71  explicit Line(Line<U> const& other);
72 
73  //! Assignment
74  Line<T> & operator=(Line<T> const & other) = default;
75 
76  //! Move assignment
77  Line<T> & operator=(Line<T> && other) = default;
78 
79  //! Get the first endpoint
80  Point2D<T> p1() const;
81 
82  //! Get the second endpoint
83  Point2D<T> p2() const;
84 
85  //! Get the center of the line
86  Point2D<T> center() const;
87 
88  //! Get the Euclidian length of this Line segment
89  double length() const;
90 
91  //! Get the Manhattan length of this Line segment
92  double manhattanLength() const;
93 
94  //! Get the angle of this line (from p1 to p2) in radians.
95  /*! \note Remember, because an Image has its origin in the top-left, a line drawn from the center of the screen
96  to the...
97  - Left has an angle of 0 radians
98  - Top has an angle of pi/2 radians
99  - Right has an angle of pi radians
100  - Bottom has an angle of -pi/2 radians */
101  double angle() const;
102 
103  //! Find the intersection of this line segment with another
104  /*! If there is no intersection then the resulting shared pointer will be empty. Returning a shared pointer here
105  leads to natural syntax like:
106 
107  @code
108  std::shared_ptr<Point2D<int>> intersection = line1.intersect<void>(line2);
109 
110  // shared_ptr evaluates to bool and returns false if it is empty
111  if (intersection)
112  {
113  Point2D<int> theIntersectionPoint = *intersection;
114  // ...
115  }
116 
117  @endcode
118 
119  @param other the other line
120 
121  @tparam promo defines how the coordinates get promoted over type T internally during our computations. If T is
122  a floating point type, then promo = void is fine, unless you need more precision (e.g., promo is double if
123  T is float). If T is an integer type, you should typically choose float or double for promo, like this:
124 
125  @code
126  nrt::Line<int> l1, l2;
127  std::shared_ptr<nrt::Point2D<int> > ii = l1.intersect<void>(l2); // not very precise, may have rounding issues
128  std::shared_ptr<nrt::Point2D<double> > ii2 = l1.intersect<double>(l2); // very precise
129  if (ii2)
130  {
131  nrt::Point2D<int> ci(*ii2); // convert coordinates back to integer if needed - truncating
132  nrt::Point2D<int> ci2(ii2->round()); // convert coordinates back to integer if needed - rounding
133  ...
134  }
135  @endcode */
136  template <typename promo>
137  std::shared_ptr<Point2D<typename promote<T, promo>::type> > intersect(nrt::Line<T> const & other);
138 
139  //! Find the intersection between the infinite lines define by this segment and another segment
140  /*! If there is no intersection then the resulting shared pointer will be empty. Returning a shared pointer here
141  leads to natural syntax like:
142 
143  @code
144  std::shared_ptr<Point2D<int>> intersection = line1.intersectInfinite<void>(line2);
145 
146  // shared_ptr evaluates to bool and returns false if it is empty
147  if (intersection)
148  {
149  Point2D<int> theIntersectionPoint = *intersection;
150  // ...
151  }
152 
153  @endcode
154 
155  @param other the other line
156 
157  @tparam promo defines how the coordinates get promoted over type T internally during our computations. If T is
158  a floating point type, then promo = void is fine, unless you need more precision (e.g., promo is double if
159  T is float). If T is an integer type, you should typically choose float or double for promo, like this:
160 
161  @code
162  nrt::Line<int> l1, l2;
163  std::shared_ptr<nrt::Point2D<int> > ii = l1.intersect<void>(l2); // not very precise, may have rounding issues
164  std::shared_ptr<nrt::Point2D<double> > ii2 = l1.intersect<double>(l2); // very precise
165  if (ii2)
166  {
167  nrt::Point2D<int> ci(*ii2); // convert coordinates back to integer if needed - truncating
168  nrt::Point2D<int> ci2(ii2->round()); // convert coordinates back to integer if needed - rounding
169  ...
170  }
171  @endcode */
172  template <typename promo>
173  std::shared_ptr<Point2D<typename promote<T, promo>::type> > intersectInfinite(nrt::Line<T> const& other);
174 
175  //! Get the perpendicular distance from this line segment to a point
176  /*! If the projection of point does not land between the two end
177  points of this line segment, it will be given an infinite distance
178  from the point.
179 
180  @param point The point to check the distance to
181  @return The perpendicular distance to the point, assuming the point projects onto the line segment.
182  If this is not the case, the distance will be infinite */
183  double perpendicularDistanceTo( Point2D<T> const & point ) const;
184 
185  protected:
186  friend class cereal::access;
187  template <class Archive>
188  void serialize(Archive& ar)
189  {
190  ar( itsP1, itsP2 );
191  }
192 
193  private:
194  Point2D<T> itsP1; //! < The first endpoint
195  Point2D<T> itsP2; //! < The second endpoint
196  };
197 
198  // ######################################################################
199  // Free functions for Line<T>
200  // ######################################################################
201 
202  //! Human-readable output to a stream: outputs {P1,P2}
203  /*! \relates Line */
204  template<class T>
205  inline std::ostream& operator<<(std::ostream &out, nrt::Line<T> const& line);
206 
207  //! Return a scaled version of the source object
208  /*! \note This does \e not have the same effect as the multiplication or division operators, which scale everything,
209  while here we only scale the object size without scaling its center coordinates.
210  \relates Line */
211  template <class T>
212  Line<T> scale(Line<T> const & src, double const factor);
213 
214  //! Return a rotated version of the source object, about its center by a given angle in radians
215  /*! \relates Line */
216  template <class T>
217  Line<T> rotate(Line<T> const & src, double const angle);
218 
219  //! Return a rotated version of the source object, about the given point and by a given angle in radians
220  /*! \relates Line */
221  template <class T>
222  Line<T> rotateAbout(Line<T> const & src, Point2D<T> const & p, double const angle);
223 
224  //! Operator overload for Line<T> == Line<T>
225  /*! \relates Line */
226  template <class T>
227  bool operator==(Line<T> const & lhs, Line<T> const & rhs);
228 
229  //! Operator overload for Line<T> != Line<T>
230  /*! \relates Line */
231  template <class T>
232  bool operator!=(Line<T> const & lhs, Line<T> const & rhs);
233 
234  //! Operator overload for Line<T> + Point2D<T>
235  /*! \relates Line */
236  template <class T>
237  Line<T> operator+(Line<T> const & lhs, Point2D<T> const & rhs);
238 
239  //! Operator overload for Point2D<T> + Line<T>
240  /*! \relates Line */
241  template <class T>
242  Line<T> operator+(Point2D<T> const & lhs, Line<T> const & rhs);
243 
244  //! Operator overload for Line<T> - Point2D<T>
245  /*! \relates Line */
246  template <class T>
247  Line<T> operator-(Line<T> const & lhs, Point2D<T> const & rhs);
248 
249  //! Operator overload for Point2D<T> - Line<T>
250  /*! \relates Line */
251  template <class T>
252  Line<T> operator-(Point2D<T> const & lhs, Line<T> const & rhs);
253 
254  //! Operator overload for Line<T> * double
255  /*! \relates Line */
256  template <class T>
257  Line<T> operator*(Line<T> const & lhs, double const rhs);
258 
259  //! Operator overload for double * Line<T>
260  /*! \relates Line */
261  template <class T>
262  Line<T> operator*(double const lhs, Line<T> const & rhs);
263 
264  //! Operator overload for Line<T> / double
265  /*! \relates Line */
266  template <class T>
267  Line<T> operator/(Line<T> const & lhs, double const rhs);
268 
269  //! Operator overload for Line<T> *= double
270  /*! \relates Line */
271  template <class T>
272  Line<T> & operator*=(Line<T> & lhs, double const rhs);
273 
274  //! Operator overload for Line<T> /= double
275  /*! \relates Line */
276  template <class T>
277  Line<T> & operator/=(Line<T> & lhs, double const rhs);
278 
279  //! Operator overload for Line<T> += Point2D<T>
280  /*! \relates Line */
281  template <class T>
282  Line<T> & operator+=(Line<T> & lhs, Point2D<T> const & rhs);
283 
284  //! Operator overload for Line<T> -= Point2D<T>
285  /*! \relates Line */
286  template <class T>
287  Line<T> & operator-=(Line<T> & lhs, Point2D<T> const & rhs);
288 }
289 
290 // Include inlined implementation details that are of no interest to the end user
292 
293 // Include explicit instantiations that are of no interest to the end user
295 
296 #endif // INCLUDE_NRT_CORE_GEOMETRY_LINE_H
297