Ocean
PixelLine.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_ADVANCED_PIXEL_LINE_H
9 #define META_OCEAN_CV_ADVANCED_PIXEL_LINE_H
10 
12 
13 #include "ocean/base/DataType.h"
14 
15 #include "ocean/cv/PixelPosition.h"
16 
17 namespace Ocean
18 {
19 
20 namespace CV
21 {
22 
23 namespace Advanced
24 {
25 
26 // Forward declaration.
27 template <typename T> class PixelLineT;
28 
29 /**
30  * Definition of the default PixelLine object with a data type allowing only positive coordinate values.
31  * @see PixelLineT
32  * @ingroup cvadvanced
33  */
35 
36 /**
37  * Definition of a PixelLine object with a data type allowing positive and negative coordinate values.
38  * @see PixelLineT
39  * @ingroup cvadvanced
40  */
42 
43 /**
44  * Definition of a vector holding pixel lines (with positive coordinate values).
45  * @see PixelLine
46  * @ingroup cvadvanced
47  */
48 typedef std::vector<PixelLine> PixelLines;
49 
50 /**
51  * Definition of a vector holding pixel lines (with positive and negative coordinate values).
52  * @see PixelLineT
53  * @ingroup cvadvanced
54  */
55 typedef std::vector<PixelLineI> PixelLinesI;
56 
57 /**
58  * This class implements a 2D line with pixel precision.
59  * @tparam T The data type that is used to store the elements of a pixel coordinate
60  * @see PixelPosition, PixelPositionI
61  * @ingroup cvadvanced
62  */
63 template <typename T>
65 {
66  public:
67 
68  /**
69  * Creates an invalid line object.
70  */
71  inline PixelLineT();
72 
73  /**
74  * Creates a new line object by two given end points.
75  * @param p0 First line end point
76  * @param p1 Second line end point
77  */
78  inline PixelLineT(const PixelPositionT<T>& p0, const PixelPositionT<T>& p1);
79 
80  /**
81  * Creates a new line object by two given end points.
82  * @param x0 First horizontal line end point
83  * @param y0 First vertical line end point
84  * @param x1 Second horizontal line end point
85  * @param y1 Second vertical line end point
86  */
87  inline PixelLineT(const T& x0, const T& y0, const T& x1, const T& y1);
88 
89  /**
90  * Returns the first end point of this line.
91  * @return First end point
92  */
93  inline const PixelPositionT<T>& p0() const;
94 
95  /**
96  * Returns the second end point of this line.
97  * @return Second end point
98  */
99  inline const PixelPositionT<T>& p1() const;
100 
101  /**
102  * Returns whether this line is horizontal.
103  * @return True, if so
104  */
105  inline bool isHorizontal() const;
106 
107  /**
108  * Returns whether this line is vertical.
109  * @return True, if so
110  */
111  inline bool isVertical() const;
112 
113  /**
114  * Returns whether this line is a point.
115  * @return True, if so
116  */
117  inline bool isPoint() const;
118 
119  /**
120  * Calculates the intersection between this line and a horizontal scan line.
121  * Beware: Make sure that the vertical scan line really intersects this line.
122  * @param y Vertical position of the scan line
123  * @param x Resulting horizontal intersection position
124  * @return True, if an intersection could be found
125  */
126  bool horizontalIntersection(const T y, T& x) const;
127 
128  /**
129  * Returns whether this line holds two valid end points.
130  * @return True, if so
131  */
132  inline bool isValid() const;
133 
134  /**
135  * Multiplies two line objects and returns the scalar product.
136  * @param line Second line to multiply
137  * @return Scalar product
138  */
139  inline typename SignedTyper<T>::Type operator*(const PixelLineT<T>& line) const;
140 
141  /**
142  * Returns whether two line objects are equal.
143  * @param line Second line object to compare
144  * @return True, if so
145  */
146  inline bool operator==(const PixelLineT<T>& line) const;
147 
148  /**
149  * Returns whether two line objects are not equal.
150  * @param line Second line object to compare
151  * @return True, if so
152  */
153  inline bool operator!=(const PixelLineT<T>& line) const;
154 
155  /**
156  * Returns whether this line holds two valid end points.
157  * @return True, if so
158  */
159  explicit inline operator bool() const;
160 
161  private:
162 
163  /// First line end point.
165 
166  /// Second line end point.
168 
169  /// Lower vertical position.
171 
172  /// Upper vertical position.
174 };
175 
176 template <typename T>
178 {
179  // nothing to do here
180 }
181 
182 template <typename T>
184  lineP0(p0),
185  lineP1(p1),
186  lineMinY(min(p0.y(), p1.y())),
187  lineMaxY(max(p0.y(), p1.y()))
188 {
189  // nothing to do here
190 }
191 
192 template <typename T>
193 inline PixelLineT<T>::PixelLineT(const T& x0, const T& y0, const T& x1, const T& y1) :
194  lineP0(x0, y0),
195  lineP1(x1, y1),
196  lineMinY(min(y0, y1)),
197  lineMaxY(max(y0, y1))
198 {
199  // nothing to do here
200 }
201 
202 template <typename T>
204 {
205  return lineP0;
206 }
207 
208 template <typename T>
210 {
211  return lineP1;
212 }
213 
214 template <typename T>
215 inline bool PixelLineT<T>::isHorizontal() const
216 {
217  ocean_assert(isValid());
218  return lineP0.y() == lineP1.y();
219 }
220 
221 template <typename T>
222 inline bool PixelLineT<T>::isVertical() const
223 {
224  ocean_assert(isValid());
225  return lineP0.x() == lineP1.x();
226 }
227 
228 template <typename T>
229 inline bool PixelLineT<T>::isPoint() const
230 {
231  ocean_assert(isValid());
232  return lineP0 == lineP1;
233 }
234 
235 template <typename T>
236 bool PixelLineT<T>::horizontalIntersection(const T y, T& x) const
237 {
238  ocean_assert(isValid());
239  ocean_assert(lineMinY <= lineMaxY);
240 
241  // y == p0.y + (p1.y - p0.y) * t
242  // t = (y - p0.y) / (p1.y - p0.y)
243 
244  // x = p0.x + (p1.x - p0.x) * t
245 
246  if (y < lineMinY || y > lineMaxY)
247  {
248  return false;
249  }
250 
251  if (lineP0.y() == lineP1.y())
252  {
253  x = min(lineP0.x(), lineP1.x());
254  }
255  else
256  {
257  typedef typename SignedTyper<T>::Type SignedType;
258 
259  const float t = float(int(y) - SignedType(lineP0.y())) / float(SignedType(lineP1.y()) - SignedType(lineP0.y()));
260  x = lineP0.x() + T(float((SignedType(lineP1.x()) - SignedType(lineP0.x()))) * t + 0.5f);
261  }
262 
263  return true;
264 }
265 
266 template <typename T>
267 inline bool PixelLineT<T>::isValid() const
268 {
269  return lineP0.isValid() && lineP1.isValid();
270 }
271 
272 template <typename T>
274 {
275  ocean_assert(isValid() && line.isValid());
276 
277  typedef typename SignedTyper<T>::Type SignedType;
278 
279  const SignedType vx0 = SignedType(lineP1.x()) - SignedType(lineP0.x());
280  const SignedType vy0 = SignedType(lineP1.y()) - SignedType(lineP0.y());
281 
282  const SignedType vx1 = SignedType(line.lineP1.x()) - SignedType(line.lineP0.x());
283  const SignedType vy1 = SignedType(line.lineP1.y()) - SignedType(line.lineP0.y());
284 
285  return vx0 * vy1 - vx1 * vy0;
286 }
287 
288 template <typename T>
289 inline bool PixelLineT<T>::operator==(const PixelLineT<T>& line) const
290 {
291  return lineP0 == line.lineP0 && lineP1 == line.lineP1;
292 }
293 
294 template <typename T>
295 inline bool PixelLineT<T>::operator!=(const PixelLineT<T>& line) const
296 {
297  return !(*this == line);
298 }
299 
300 template <typename T>
301 inline PixelLineT<T>::operator bool() const
302 {
303  return isValid();
304 }
305 
306 }
307 
308 }
309 
310 }
311 
312 #endif // META_OCEAN_CV_ADVANCED_PIXEL_LINE_H
This class implements a 2D line with pixel precision.
Definition: PixelLine.h:65
bool isHorizontal() const
Returns whether this line is horizontal.
Definition: PixelLine.h:215
bool isVertical() const
Returns whether this line is vertical.
Definition: PixelLine.h:222
T lineMinY
Lower vertical position.
Definition: PixelLine.h:170
PixelPositionT< T > lineP0
First line end point.
Definition: PixelLine.h:164
PixelLineT()
Creates an invalid line object.
Definition: PixelLine.h:177
PixelPositionT< T > lineP1
Second line end point.
Definition: PixelLine.h:167
bool operator!=(const PixelLineT< T > &line) const
Returns whether two line objects are not equal.
Definition: PixelLine.h:295
T lineMaxY
Upper vertical position.
Definition: PixelLine.h:173
SignedTyper< T >::Type operator*(const PixelLineT< T > &line) const
Multiplies two line objects and returns the scalar product.
Definition: PixelLine.h:273
bool isValid() const
Returns whether this line holds two valid end points.
Definition: PixelLine.h:267
const PixelPositionT< T > & p0() const
Returns the first end point of this line.
Definition: PixelLine.h:203
bool isPoint() const
Returns whether this line is a point.
Definition: PixelLine.h:229
const PixelPositionT< T > & p1() const
Returns the second end point of this line.
Definition: PixelLine.h:209
bool operator==(const PixelLineT< T > &line) const
Returns whether two line objects are equal.
Definition: PixelLine.h:289
bool horizontalIntersection(const T y, T &x) const
Calculates the intersection between this line and a horizontal scan line.
Definition: PixelLine.h:236
This class implements a 2D pixel position with pixel precision.
Definition: PixelPosition.h:65
T Type
Definition of the signed data type, if existing.
Definition: DataType.h:294
std::vector< PixelLine > PixelLines
Definition of a vector holding pixel lines (with positive coordinate values).
Definition: PixelLine.h:48
PixelLineT< int > PixelLineI
Definition of a PixelLine object with a data type allowing positive and negative coordinate values.
Definition: PixelLine.h:41
PixelLineT< unsigned int > PixelLine
Definition of the default PixelLine object with a data type allowing only positive coordinate values.
Definition: PixelLine.h:27
std::vector< PixelLineI > PixelLinesI
Definition of a vector holding pixel lines (with positive and negative coordinate values).
Definition: PixelLine.h:55
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15