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