Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkLine.h
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef MITKLINE_H_HEADER_INCLUDED_C19C01E2
18 #define MITKLINE_H_HEADER_INCLUDED_C19C01E2
19 
20 #include "mitkNumericTypes.h"
21 #include <itkMatrix.h>
22 #include <itkTransform.h>
23 #include <vnl/vnl_cross.h>
24 #include <vnl/vnl_vector.h>
25 
26 namespace mitk
27 {
28  //##Documentation
29  //## @brief Descibes a line
30  //## @ingroup Geometry
31  template <class TCoordRep, unsigned int NPointDimension = 3>
32  class Line
33  {
34  public:
35  Line()
36  {
37  m_Point.Fill(0);
38  m_Direction.Fill(0);
39  }
40 
41  //##Documentation
42  //## @brief Define line by point and direction
43  //##
44  //## Length of direction defines the the length of the line
45  Line(const itk::Point<TCoordRep, NPointDimension> &point, const itk::Vector<TCoordRep, NPointDimension> &direction)
46  {
47  this->m_Point = point;
48  this->m_Direction = direction;
49  }
50 
51  //##Documentation
52  //## @brief Get start point of the line
53  const itk::Point<TCoordRep, NPointDimension> &GetPoint() const { return m_Point; }
54  //##Documentation
55  //## @brief Get start point of the line
56  itk::Point<TCoordRep, NPointDimension> &GetPoint() { return m_Point; }
57  //##Documentation
58  //## @brief Get point on the line with parameter @a t
59  //##
60  //## @return m_Point+t*m_Direction
61  const itk::Point<TCoordRep, NPointDimension> GetPoint(TCoordRep t) const { return m_Point + m_Direction * t; }
62  //##Documentation
63  //## @brief Set/change start point of the line
64  void SetPoint(const itk::Point<TCoordRep, NPointDimension> &point1)
65  {
66  itk::Point<TCoordRep, NPointDimension> point2;
67  point2 = m_Point + m_Direction;
68  m_Point = point1;
69  m_Direction = point2.GetVectorFromOrigin() - point1.GetVectorFromOrigin();
70  }
71 
72  //##Documentation
73  //## @brief Get the direction vector of the line
74  const itk::Vector<TCoordRep, NPointDimension> &GetDirection() const { return m_Direction; }
75  //##Documentation
76  //## @brief Get the direction vector of the line
77  itk::Vector<TCoordRep, NPointDimension> &GetDirection() { return m_Direction; }
78  //##Documentation
79  //## @brief Set the direction vector of the line
80  void SetDirection(const itk::Vector<TCoordRep, NPointDimension> &direction) { m_Direction = direction; }
81  //##Documentation
82  //## @brief Define line by point and direction
83  //##
84  //## Length of direction defines the the length of the line
85  void Set(const itk::Point<TCoordRep, NPointDimension> &point,
86  const itk::Vector<TCoordRep, NPointDimension> &direction)
87  {
88  this->m_Point = point;
89  this->m_Direction = direction;
90  }
91 
92  //##Documentation
93  //## @brief Define line by two points
94  void SetPoints(const itk::Point<TCoordRep, NPointDimension> &point1,
95  const itk::Point<TCoordRep, NPointDimension> &point2)
96  {
97  this->m_Point = point1;
98  // this->m_Direction.sub( point2, point1 );
99  m_Direction = point2 - point1;
100  }
101 
102  //##Documentation
103  //## @brief Set/change start point of the line
104  void SetPoint1(const itk::Point<TCoordRep, NPointDimension> &point1)
105  {
106  itk::Vector<TCoordRep, NPointDimension> point2;
107  point2 = m_Point.GetVectorFromOrigin() + m_Direction;
108 
109  m_Point = point1;
110  m_Direction = point2 - point1.GetVectorFromOrigin();
111  }
112 
113  //##Documentation
114  //## @brief Get start point of the line
115  const itk::Point<TCoordRep, NPointDimension> &GetPoint1() const { return m_Point; }
116  //##Documentation
117  //## @brief Set/change end point of the line
118  void SetPoint2(const itk::Point<TCoordRep, NPointDimension> &point2) { m_Direction = point2 - m_Point; }
119  //##Documentation
120  //## @brief Get end point of the line
121  itk::Point<TCoordRep, NPointDimension> GetPoint2() const
122  {
123  itk::Point<TCoordRep, NPointDimension> point2;
124  point2 = m_Point + m_Direction;
125  return point2;
126  }
127 
128  //##Documentation
129  //## @brief Transform the line with a Transform
130  void Transform(itk::Transform<TCoordRep, NPointDimension, NPointDimension> &transform)
131  {
132  m_Direction = transform.TransformVector(m_Direction);
133  m_Point = transform.TransformPoint(m_Point);
134  }
135 
136  //##Documentation
137  //## @brief Transform the line with a matrix
138  //##
139  //## Only the direction will be changed, not the start point.
140  void Transform(const itk::Matrix<TCoordRep, NPointDimension, NPointDimension> &matrix)
141  {
142  m_Direction = matrix * m_Direction;
143  }
144 
145  //##Documentation
146  //## @brief Distance of a point from the line
147  double Distance(const itk::Point<TCoordRep, NPointDimension> &point) const
148  {
149  itk::Vector<TCoordRep, NPointDimension> diff;
150  diff = Project(point) - point;
151  return diff.GetNorm();
152  }
153 
154  //##Documentation
155  //## @brief Project a point on the line
156  itk::Point<TCoordRep, NPointDimension> Project(const itk::Point<TCoordRep, NPointDimension> &point) const
157  {
158  if (m_Direction.GetNorm() == 0)
159  return this->m_Point;
160 
161  itk::Vector<TCoordRep, NPointDimension> diff;
162  diff = point - this->m_Point;
163 
164  itk::Vector<TCoordRep, NPointDimension> normalizedDirection = m_Direction;
165  normalizedDirection.Normalize();
166 
167  normalizedDirection *= dot_product(diff.GetVnlVector(), normalizedDirection.GetVnlVector());
168 
169  return this->m_Point + normalizedDirection;
170  }
171 
172  //##Documentation
173  //## @brief Test if a point is part of the line
174  //##
175  //## Length of the direction vector defines the length of the line
176  bool IsPartOfStraightLine(const itk::Point<TCoordRep, NPointDimension> &point) const
177  {
178  if (Distance(point) > eps)
179  return false;
180 
181  itk::Vector<TCoordRep, NPointDimension> diff;
182  diff = point - this->m_Point;
183 
184  if (diff * m_Direction < 0)
185  return false;
186 
187  if (diff.GetSquaredNorm() <= m_Direction.GetSquaredNorm())
188  return true;
189 
190  return false;
191  }
192 
193  //##Documentation
194  //## @brief Test if a point is part of the line (line having infinite length)
195  bool IsPartOfLine(const itk::Point<TCoordRep, NPointDimension> &point) const
196  {
197  if (Distance(point) < eps)
198  return true;
199 
200  return false;
201  }
202 
203  //##Documentation
204  //## @brief Test if a lines is parallel to this line
206  {
207  vnl_vector<TCoordRep> normal;
208 
209  normal = vnl_cross_3d(m_Direction.GetVnlVector(), line.GetDirection().GetVnlVector());
210 
211  if (normal.squared_magnitude() < eps)
212  return true;
213 
214  return false;
215  }
216 
217  //##Documentation
218  //## @brief Test if a line is part of the line (line having infinite length)
220  {
221  return (Distance(line.GetPoint()) < 0) && (IsParallel(line));
222  }
223 
224  //##Documentation
225  //## @brief Test if the two lines are identical
226  //##
227  //## Start point and direction and length of direction vector must be
228  //## equal for identical lines.
230  {
231  itk::Vector<TCoordRep, NPointDimension> diff;
232  diff = GetPoint1() - line.GetPoint1();
233  if (diff.GetSquaredNorm() > eps)
234  return false;
235  diff = GetPoint2() - line.GetPoint2();
236  if (diff.GetSquaredNorm() > eps)
237  return false;
238  return true;
239  }
240 
241  //##Documentation
242  //## @brief Set the line by another line
244  {
245  m_Point = line.GetPoint();
246  m_Direction = line.GetDirection();
247  return *this;
248  }
249 
250  //##Documentation
251  //## @brief Test if two lines are not identical
252  //##
253  //## \sa operator==
254  bool operator!=(const Line<TCoordRep, NPointDimension> &line) const { return !((*this) == line); }
255  //##Documentation
256  //## @brief Calculates the intersection points of a straight line in 2D
257  //## with a rectangle
258  //##
259  //## @param x1,y1,x2,y2 rectangle
260  //## @param p,d straight line: p point on it, d direction of line
261  //## @param s1 first intersection point (valid only if s_num>0)
262  //## @param s2 second intersection point (valid only if s_num==2)
263  //## @return number of intersection points (0<=s_num<=2)
264  static int RectangleLineIntersection(TCoordRep x1,
265  TCoordRep y1,
266  TCoordRep x2,
267  TCoordRep y2,
268  itk::Point<TCoordRep, 2> p,
269  itk::Vector<TCoordRep, 2> d,
270  itk::Point<TCoordRep, 2> &s1,
271  itk::Point<TCoordRep, 2> &s2)
272  {
273  int s_num;
274  TCoordRep t;
275  s_num = 0;
276 
277  /*test if intersecting with the horizontal axis*/
278  if (fabs(d[0]) > eps)
279  {
280  t = (x1 - p[0]) / d[0];
281  itk::Point<TCoordRep, 2> l = p + d * t;
282  if ((l[1] >= y1) && (l[1] < y2))
283  { // yes, intersection point within the bounds of the border-line
284  if (s_num)
285  s2 = l;
286  else
287  s1 = l;
288  ++s_num;
289  }
290  }
291 
292  if (fabs(d[0]) > eps)
293  {
294  t = (x2 - p[0]) / d[0];
295  itk::Point<TCoordRep, 2> l = p + d * t;
296 
297  if ((l[1] >= y1) && (l[1] < y2))
298  { // yes, intersection point within the bounds of the border-line
299  if (s_num)
300  s2 = l;
301  else
302  s1 = l;
303  ++s_num;
304  }
305  }
306 
307  /*test if intersecting with the vertical axis*/
308  if (fabs(d[1]) > eps)
309  {
310  t = (y1 - p[1]) / d[1];
311  itk::Point<TCoordRep, 2> l = p + d * t;
312 
313  if ((l[0] >= x1) && (l[0] < x2))
314  { // yes, intersection point within the bounds of the border-line
315  if (s_num)
316  s2 = l;
317  else
318  s1 = l;
319  ++s_num;
320  }
321  }
322 
323  if (fabs(d[1]) > eps)
324  {
325  t = (y2 - p[1]) / d[1];
326  itk::Point<TCoordRep, 2> l = p + d * t;
327  if ((l[0] >= x1) && (l[0] < x2))
328  { // yes, intersection point within the bounds of the border-line
329  if (s_num)
330  s2 = l;
331  else
332  s1 = l;
333  ++s_num;
334  }
335  }
336  return s_num;
337  }
338 
350  static int BoxLineIntersection(TCoordRep x1,
351  TCoordRep y1,
352  TCoordRep z1,
353  TCoordRep x2,
354  TCoordRep y2,
355  TCoordRep z2,
356  itk::Point<TCoordRep, 3> p,
357  itk::Vector<TCoordRep, 3> d,
358  itk::Point<TCoordRep, 3> &s1,
359  itk::Point<TCoordRep, 3> &s2)
360  {
361  int num = 0;
362 
363  ScalarType box[6];
364  box[0] = x1;
365  box[1] = x2;
366  box[2] = y1;
367  box[3] = y2;
368  box[4] = z1;
369  box[5] = z2;
370 
371  itk::Point<TCoordRep, 3> point;
372 
373  int i, j;
374  for (i = 0; i < 6; ++i)
375  {
376  j = i / 2;
377  if (fabs(d[j]) > eps)
378  {
379  ScalarType lambda = (box[i] - p[j]) / d[j];
380 
381  point = p + d * lambda;
382 
383  int k = (j + 1) % 3;
384  int l = (j + 2) % 3;
385 
386  if ((((point[k] >= box[k * 2]) && (point[k] <= box[k * 2 + 1])) ||
387  ((point[k] <= box[k * 2]) && (point[k] >= box[k * 2 + 1]))) &&
388  (((point[l] >= box[l * 2]) && (point[l] <= box[l * 2 + 1])) ||
389  ((point[l] <= box[l * 2]) && (point[l] >= box[l * 2 + 1])))
390 
391  )
392  {
393  if (num == 0)
394  {
395  s1 = point;
396  }
397  else
398  {
399  s2 = point;
400  }
401  ++num;
402  }
403  }
404  }
405  return num;
406  }
407 
408  protected:
409  itk::Point<TCoordRep, NPointDimension> m_Point;
410  itk::Vector<TCoordRep, NPointDimension> m_Direction;
411  };
412 
414 
415 } // namespace mitk
416 
417 #endif /* MITKLINE_H_HEADER_INCLUDED_C19C01E2 */
void SetPoint2(const itk::Point< TCoordRep, NPointDimension > &point2)
Set/change end point of the line.
Definition: mitkLine.h:118
const itk::Point< TCoordRep, NPointDimension > & GetPoint1() const
Get start point of the line.
Definition: mitkLine.h:115
Descibes a line.
Definition: mitkLine.h:32
static char * line
Definition: svm.cpp:2884
double Distance(const itk::Point< TCoordRep, NPointDimension > &point) const
Distance of a point from the line.
Definition: mitkLine.h:147
bool operator!=(const Line< TCoordRep, NPointDimension > &line) const
Test if two lines are not identical.
Definition: mitkLine.h:254
itk::Point< TCoordRep, NPointDimension > & GetPoint()
Get start point of the line.
Definition: mitkLine.h:56
void SetDirection(const itk::Vector< TCoordRep, NPointDimension > &direction)
Set the direction vector of the line.
Definition: mitkLine.h:80
double ScalarType
void SetPoint(const itk::Point< TCoordRep, NPointDimension > &point1)
Set/change start point of the line.
Definition: mitkLine.h:64
Line< ScalarType, 3 > Line3D
Definition: mitkLine.h:413
DataCollection - Class to facilitate loading/accessing structured data.
itk::Point< TCoordRep, NPointDimension > m_Point
Definition: mitkLine.h:409
bool IsParallel(const Line< TCoordRep, NPointDimension > &line) const
Test if a lines is parallel to this line.
Definition: mitkLine.h:205
static int BoxLineIntersection(TCoordRep x1, TCoordRep y1, TCoordRep z1, TCoordRep x2, TCoordRep y2, TCoordRep z2, itk::Point< TCoordRep, 3 > p, itk::Vector< TCoordRep, 3 > d, itk::Point< TCoordRep, 3 > &s1, itk::Point< TCoordRep, 3 > &s2)
Calculates the intersection points of a straight line in 3D with a box.
Definition: mitkLine.h:350
const itk::Vector< TCoordRep, NPointDimension > & GetDirection() const
Get the direction vector of the line.
Definition: mitkLine.h:74
const itk::Point< TCoordRep, NPointDimension > GetPoint(TCoordRep t) const
Get point on the line with parameter t.
Definition: mitkLine.h:61
const itk::Point< TCoordRep, NPointDimension > & GetPoint() const
Get start point of the line.
Definition: mitkLine.h:53
void Transform(itk::Transform< TCoordRep, NPointDimension, NPointDimension > &transform)
Transform the line with a Transform.
Definition: mitkLine.h:130
void SetPoints(const itk::Point< TCoordRep, NPointDimension > &point1, const itk::Point< TCoordRep, NPointDimension > &point2)
Define line by two points.
Definition: mitkLine.h:94
bool IsPartOfLine(const itk::Point< TCoordRep, NPointDimension > &point) const
Test if a point is part of the line (line having infinite length)
Definition: mitkLine.h:195
bool IsPartOfStraightLine(const itk::Point< TCoordRep, NPointDimension > &point) const
Test if a point is part of the line.
Definition: mitkLine.h:176
itk::Vector< TCoordRep, NPointDimension > m_Direction
Definition: mitkLine.h:410
itk::Point< TCoordRep, NPointDimension > Project(const itk::Point< TCoordRep, NPointDimension > &point) const
Project a point on the line.
Definition: mitkLine.h:156
itk::Point< TCoordRep, NPointDimension > GetPoint2() const
Get end point of the line.
Definition: mitkLine.h:121
static int RectangleLineIntersection(TCoordRep x1, TCoordRep y1, TCoordRep x2, TCoordRep y2, itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d, itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2)
Calculates the intersection points of a straight line in 2D with a rectangle.
Definition: mitkLine.h:264
MITKCORE_EXPORT const ScalarType eps
bool IsPartOfLine(const Line< TCoordRep, NPointDimension > &line) const
Test if a line is part of the line (line having infinite length)
Definition: mitkLine.h:219
itk::Vector< TCoordRep, NPointDimension > & GetDirection()
Get the direction vector of the line.
Definition: mitkLine.h:77
void Transform(const itk::Matrix< TCoordRep, NPointDimension, NPointDimension > &matrix)
Transform the line with a matrix.
Definition: mitkLine.h:140
void SetPoint1(const itk::Point< TCoordRep, NPointDimension > &point1)
Set/change start point of the line.
Definition: mitkLine.h:104
void Set(const itk::Point< TCoordRep, NPointDimension > &point, const itk::Vector< TCoordRep, NPointDimension > &direction)
Define line by point and direction.
Definition: mitkLine.h:85
bool operator==(const Line< TCoordRep, NPointDimension > &line) const
Test if the two lines are identical.
Definition: mitkLine.h:229
const Line< TCoordRep, NPointDimension > & operator=(const Line< TCoordRep, NPointDimension > &line)
Set the line by another line.
Definition: mitkLine.h:243
Line(const itk::Point< TCoordRep, NPointDimension > &point, const itk::Vector< TCoordRep, NPointDimension > &direction)
Define line by point and direction.
Definition: mitkLine.h:45