Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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