Medical Imaging Interaction Toolkit  2026.06.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 {
35  template <class TCoordRep, unsigned int NPointDimension = 3>
36  class Line
37  {
38  public:
39  Line()
40  {
41  m_Point.Fill(0);
42  m_Direction.Fill(0);
43  }
44 
52  Line(const itk::Point<TCoordRep, NPointDimension> &point, const itk::Vector<TCoordRep, NPointDimension> &direction)
53  {
54  this->m_Point = point;
55  this->m_Direction = direction;
56  }
57 
59  const itk::Point<TCoordRep, NPointDimension> &GetPoint() const { return m_Point; }
60 
62  itk::Point<TCoordRep, NPointDimension> &GetPoint() { return m_Point; }
63 
69  const itk::Point<TCoordRep, NPointDimension> GetPoint(TCoordRep t) const { return m_Point + m_Direction * t; }
70 
78  void SetPoint(const itk::Point<TCoordRep, NPointDimension> &point1)
79  {
80  itk::Point<TCoordRep, NPointDimension> point2;
81  point2 = m_Point + m_Direction;
82  m_Point = point1;
83  m_Direction = point2.GetVectorFromOrigin() - point1.GetVectorFromOrigin();
84  }
85 
87  const itk::Vector<TCoordRep, NPointDimension> &GetDirection() const { return m_Direction; }
88 
90  itk::Vector<TCoordRep, NPointDimension> &GetDirection() { return m_Direction; }
91 
96  void SetDirection(const itk::Vector<TCoordRep, NPointDimension> &direction) { m_Direction = direction; }
97 
105  void Set(const itk::Point<TCoordRep, NPointDimension> &point,
106  const itk::Vector<TCoordRep, NPointDimension> &direction)
107  {
108  this->m_Point = point;
109  this->m_Direction = direction;
110  }
111 
117  void SetPoints(const itk::Point<TCoordRep, NPointDimension> &point1,
118  const itk::Point<TCoordRep, NPointDimension> &point2)
119  {
120  this->m_Point = point1;
121  // this->m_Direction.sub( point2, point1 );
122  m_Direction = point2 - point1;
123  }
124 
132  void SetPoint1(const itk::Point<TCoordRep, NPointDimension> &point1)
133  {
134  itk::Vector<TCoordRep, NPointDimension> point2;
135  point2 = m_Point.GetVectorFromOrigin() + m_Direction;
136 
137  m_Point = point1;
138  m_Direction = point2 - point1.GetVectorFromOrigin();
139  }
140 
142  const itk::Point<TCoordRep, NPointDimension> &GetPoint1() const { return m_Point; }
143 
150  void SetPoint2(const itk::Point<TCoordRep, NPointDimension> &point2) { m_Direction = point2 - m_Point; }
151 
156  itk::Point<TCoordRep, NPointDimension> GetPoint2() const
157  {
158  itk::Point<TCoordRep, NPointDimension> point2;
159  point2 = m_Point + m_Direction;
160  return point2;
161  }
162 
169  void Transform(itk::Transform<TCoordRep, NPointDimension, NPointDimension> &transform)
170  {
171  m_Direction = transform.TransformVector(m_Direction);
172  m_Point = transform.TransformPoint(m_Point);
173  }
174 
181  void Transform(const itk::Matrix<TCoordRep, NPointDimension, NPointDimension> &matrix)
182  {
183  m_Direction = matrix * m_Direction;
184  }
185 
191  double Distance(const itk::Point<TCoordRep, NPointDimension> &point) const
192  {
193  itk::Vector<TCoordRep, NPointDimension> diff;
194  diff = Project(point) - point;
195  return diff.GetNorm();
196  }
197 
205  itk::Point<TCoordRep, NPointDimension> Project(const itk::Point<TCoordRep, NPointDimension> &point) const
206  {
207  if (m_Direction.GetNorm() == 0)
208  return this->m_Point;
209 
210  itk::Vector<TCoordRep, NPointDimension> diff;
211  diff = point - this->m_Point;
212 
213  itk::Vector<TCoordRep, NPointDimension> normalizedDirection = m_Direction;
214  normalizedDirection.Normalize();
215 
216  normalizedDirection *= dot_product(diff.GetVnlVector(), normalizedDirection.GetVnlVector());
217 
218  return this->m_Point + normalizedDirection;
219  }
220 
229  bool IsPartOfStraightLine(const itk::Point<TCoordRep, NPointDimension> &point) const
230  {
231  if (Distance(point) > eps)
232  return false;
233 
234  itk::Vector<TCoordRep, NPointDimension> diff;
235  diff = point - this->m_Point;
236 
237  if (diff * m_Direction < 0)
238  return false;
239 
240  if (diff.GetSquaredNorm() <= m_Direction.GetSquaredNorm())
241  return true;
242 
243  return false;
244  }
245 
251  bool IsPartOfLine(const itk::Point<TCoordRep, NPointDimension> &point) const
252  {
253  if (Distance(point) < eps)
254  return true;
255 
256  return false;
257  }
258 
267  {
268  vnl_vector<TCoordRep> normal;
269 
270  normal = vnl_cross_3d(m_Direction.GetVnlVector(), line.GetDirection().GetVnlVector());
271 
272  if (normal.squared_magnitude() < eps)
273  return true;
274 
275  return false;
276  }
277 
286  {
287  return (Distance(line.GetPoint()) < 0) && (IsParallel(line));
288  }
289 
299  {
300  itk::Vector<TCoordRep, NPointDimension> diff;
301  diff = GetPoint1() - line.GetPoint1();
302  if (diff.GetSquaredNorm() > eps)
303  return false;
304  diff = GetPoint2() - line.GetPoint2();
305  if (diff.GetSquaredNorm() > eps)
306  return false;
307  return true;
308  }
309 
316  {
317  m_Point = line.GetPoint();
318  m_Direction = line.GetDirection();
319  return *this;
320  }
321 
326  bool operator!=(const Line<TCoordRep, NPointDimension> &line) const { return !((*this) == line); }
327 
341  static int RectangleLineIntersection(TCoordRep x1,
342  TCoordRep y1,
343  TCoordRep x2,
344  TCoordRep y2,
345  itk::Point<TCoordRep, 2> p,
346  itk::Vector<TCoordRep, 2> d,
347  itk::Point<TCoordRep, 2> &s1,
348  itk::Point<TCoordRep, 2> &s2)
349  {
350  int s_num;
351  TCoordRep t;
352  s_num = 0;
353 
354  /*test if intersecting with the horizontal axis*/
355  if (fabs(d[0]) > eps)
356  {
357  t = (x1 - p[0]) / d[0];
358  itk::Point<TCoordRep, 2> l = p + d * t;
359  if ((l[1] >= y1) && (l[1] < y2))
360  { // yes, intersection point within the bounds of the border-line
361  if (s_num)
362  s2 = l;
363  else
364  s1 = l;
365  ++s_num;
366  }
367  }
368 
369  if (fabs(d[0]) > eps)
370  {
371  t = (x2 - p[0]) / d[0];
372  itk::Point<TCoordRep, 2> l = p + d * t;
373 
374  if ((l[1] >= y1) && (l[1] < y2))
375  { // yes, intersection point within the bounds of the border-line
376  if (s_num)
377  s2 = l;
378  else
379  s1 = l;
380  ++s_num;
381  }
382  }
383 
384  /*test if intersecting with the vertical axis*/
385  if (fabs(d[1]) > eps)
386  {
387  t = (y1 - p[1]) / d[1];
388  itk::Point<TCoordRep, 2> l = p + d * t;
389 
390  if ((l[0] >= x1) && (l[0] < x2))
391  { // yes, intersection point within the bounds of the border-line
392  if (s_num)
393  s2 = l;
394  else
395  s1 = l;
396  ++s_num;
397  }
398  }
399 
400  if (fabs(d[1]) > eps)
401  {
402  t = (y2 - p[1]) / d[1];
403  itk::Point<TCoordRep, 2> l = p + d * t;
404  if ((l[0] >= x1) && (l[0] < x2))
405  { // yes, intersection point within the bounds of the border-line
406  if (s_num)
407  s2 = l;
408  else
409  s1 = l;
410  ++s_num;
411  }
412  }
413  return s_num;
414  }
415 
427  static int BoxLineIntersection(TCoordRep x1,
428  TCoordRep y1,
429  TCoordRep z1,
430  TCoordRep x2,
431  TCoordRep y2,
432  TCoordRep z2,
433  itk::Point<TCoordRep, 3> p,
434  itk::Vector<TCoordRep, 3> d,
435  itk::Point<TCoordRep, 3> &s1,
436  itk::Point<TCoordRep, 3> &s2)
437  {
438  int num = 0;
439 
440  ScalarType box[6];
441  box[0] = x1;
442  box[1] = x2;
443  box[2] = y1;
444  box[3] = y2;
445  box[4] = z1;
446  box[5] = z2;
447 
448  itk::Point<TCoordRep, 3> point;
449 
450  int i, j;
451  for (i = 0; i < 6; ++i)
452  {
453  j = i / 2;
454  if (fabs(d[j]) > eps)
455  {
456  ScalarType lambda = (box[i] - p[j]) / d[j];
457 
458  point = p + d * lambda;
459 
460  int k = (j + 1) % 3;
461  int l = (j + 2) % 3;
462 
463  if ((((point[k] >= box[k * 2]) && (point[k] <= box[k * 2 + 1])) ||
464  ((point[k] <= box[k * 2]) && (point[k] >= box[k * 2 + 1]))) &&
465  (((point[l] >= box[l * 2]) && (point[l] <= box[l * 2 + 1])) ||
466  ((point[l] <= box[l * 2]) && (point[l] >= box[l * 2 + 1])))
467 
468  )
469  {
470  if (num == 0)
471  {
472  s1 = point;
473  }
474  else
475  {
476  s2 = point;
477  }
478  ++num;
479  }
480  }
481  }
482  return num;
483  }
484 
485  protected:
486  itk::Point<TCoordRep, NPointDimension> m_Point;
487  itk::Vector<TCoordRep, NPointDimension> m_Direction;
488  };
489 
491 
492 } // namespace mitk
493 
494 #endif
Describes a line in N-dimensional space.
Definition: mitkLine.h:37
void SetPoint2(const itk::Point< TCoordRep, NPointDimension > &point2)
Set/change end point of the line.
Definition: mitkLine.h:150
const itk::Point< TCoordRep, NPointDimension > & GetPoint1() const
Get start point of the line.
Definition: mitkLine.h:142
itk::Point< TCoordRep, NPointDimension > m_Point
Definition: mitkLine.h:486
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:427
bool IsPartOfLine(const Line< TCoordRep, NPointDimension > &line) const
Test if another line is part of this line (line having infinite length).
Definition: mitkLine.h:285
const itk::Point< TCoordRep, NPointDimension > & GetPoint() const
Get start point of the line (const).
Definition: mitkLine.h:59
itk::Point< TCoordRep, NPointDimension > Project(const itk::Point< TCoordRep, NPointDimension > &point) const
Project a point onto the line.
Definition: mitkLine.h:205
double Distance(const itk::Point< TCoordRep, NPointDimension > &point) const
Compute the distance of a point from the line.
Definition: mitkLine.h:191
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:341
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:251
Line(const itk::Point< TCoordRep, NPointDimension > &point, const itk::Vector< TCoordRep, NPointDimension > &direction)
Define line by point and direction.
Definition: mitkLine.h:52
const Line< TCoordRep, NPointDimension > & operator=(const Line< TCoordRep, NPointDimension > &line)
Set the line by another line (copy assignment).
Definition: mitkLine.h:315
itk::Vector< TCoordRep, NPointDimension > & GetDirection()
Get the direction vector of the line (non-const).
Definition: mitkLine.h:90
void SetPoints(const itk::Point< TCoordRep, NPointDimension > &point1, const itk::Point< TCoordRep, NPointDimension > &point2)
Define line by two points.
Definition: mitkLine.h:117
void SetDirection(const itk::Vector< TCoordRep, NPointDimension > &direction)
Set the direction vector of the line.
Definition: mitkLine.h:96
bool operator==(const Line< TCoordRep, NPointDimension > &line) const
Test if the two lines are identical.
Definition: mitkLine.h:298
void Transform(itk::Transform< TCoordRep, NPointDimension, NPointDimension > &transform)
Transform the line with an ITK Transform.
Definition: mitkLine.h:169
void Set(const itk::Point< TCoordRep, NPointDimension > &point, const itk::Vector< TCoordRep, NPointDimension > &direction)
Define line by point and direction.
Definition: mitkLine.h:105
const itk::Vector< TCoordRep, NPointDimension > & GetDirection() const
Get the direction vector of the line (const).
Definition: mitkLine.h:87
bool operator!=(const Line< TCoordRep, NPointDimension > &line) const
Test if two lines are not identical.
Definition: mitkLine.h:326
bool IsParallel(const Line< TCoordRep, NPointDimension > &line) const
Test if a line is parallel to this line.
Definition: mitkLine.h:266
bool IsPartOfStraightLine(const itk::Point< TCoordRep, NPointDimension > &point) const
Test if a point is part of the line segment.
Definition: mitkLine.h:229
const itk::Point< TCoordRep, NPointDimension > GetPoint(TCoordRep t) const
Get point on the line at parameter t.
Definition: mitkLine.h:69
void SetPoint1(const itk::Point< TCoordRep, NPointDimension > &point1)
Set/change start point of the line.
Definition: mitkLine.h:132
itk::Vector< TCoordRep, NPointDimension > m_Direction
Definition: mitkLine.h:487
void SetPoint(const itk::Point< TCoordRep, NPointDimension > &point1)
Set/change start point of the line.
Definition: mitkLine.h:78
void Transform(const itk::Matrix< TCoordRep, NPointDimension, NPointDimension > &matrix)
Transform the line with a matrix.
Definition: mitkLine.h:181
itk::Point< TCoordRep, NPointDimension > & GetPoint()
Get start point of the line (non-const).
Definition: mitkLine.h:62
itk::Point< TCoordRep, NPointDimension > GetPoint2() const
Get end point of the line.
Definition: mitkLine.h:156
Convenience header that includes all MITK numeric types.
Find image slices visible on a given plane.
MITKCORE_EXPORT const ScalarType eps
Epsilon value for floating point comparison (vnl_math::eps * 100).
Line< ScalarType, 3 > Line3D
Definition: mitkLine.h:490
double ScalarType
Scalar type used throughout MITK for geometric computations.