Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPlanarBezierCurve.cpp
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 #include "mitkPlanarBezierCurve.h"
14 #include <mitkProperties.h>
15 
16 #include <limits>
17 
19  : FEATURE_ID_LENGTH(Superclass::AddFeature("Length", "mm")), m_NumberOfSegments(100)
20 {
22  this->SetNumberOfPolyLines(1);
24 }
25 
27 {
28  double length = 0.0;
29 
30  for (unsigned int i = 0; i < m_NumberOfSegments; ++i)
31  length += static_cast<Point2D>(m_PolyLines[0][i]).EuclideanDistanceTo(static_cast<Point2D>(m_PolyLines[0][i + 1]));
32 
33  this->SetQuantity(FEATURE_ID_LENGTH, length);
34 }
35 
37 {
38  return m_NumberOfSegments;
39 }
40 
41 void mitk::PlanarBezierCurve::SetNumberOfSegments(unsigned int numSegments)
42 {
43  m_NumberOfSegments = std::max(1U, numSegments);
44 
45  if (this->IsPlaced())
46  {
47  this->GeneratePolyLine();
48  this->Modified();
49  }
50 }
51 
53 {
54  this->ClearHelperPolyLines();
55 
56  unsigned int numHelperPolyLinePoints = m_ControlPoints.size();
57 
58  for (unsigned int i = 0; i < numHelperPolyLinePoints; ++i)
60 }
61 
63 {
64  this->ClearPolyLines();
65 
66  const unsigned int numPolyLinePoints = m_NumberOfSegments + 1;
67 
68  for (unsigned int i = 0; i < numPolyLinePoints; ++i)
69  this->AppendPointToPolyLine(0, this->ComputeDeCasteljauPoint(i / static_cast<ScalarType>(m_NumberOfSegments)));
70 }
71 
72 mitk::Point2D mitk::PlanarBezierCurve::ComputeDeCasteljauPoint(mitk::ScalarType t)
73 {
74  unsigned int n = m_ControlPoints.size() - 1;
75 
76  if (m_DeCasteljauPoints.size() != n)
77  m_DeCasteljauPoints.resize(n);
78 
79  for (unsigned int i = 0; i < n; ++i)
80  {
81  m_DeCasteljauPoints[i][0] = (1 - t) * m_ControlPoints[i][0] + t * m_ControlPoints[i + 1][0];
82  m_DeCasteljauPoints[i][1] = (1 - t) * m_ControlPoints[i][1] + t * m_ControlPoints[i + 1][1];
83  }
84 
85  for (--n; n > 0; --n)
86  {
87  for (unsigned int i = 0; i < n; ++i)
88  {
89  m_DeCasteljauPoints[i][0] = (1 - t) * m_DeCasteljauPoints[i][0] + t * m_DeCasteljauPoints[i + 1][0];
90  m_DeCasteljauPoints[i][1] = (1 - t) * m_DeCasteljauPoints[i][1] + t * m_DeCasteljauPoints[i + 1][1];
91  }
92  }
93 
94  return m_DeCasteljauPoints[0];
95 }
96 
97 int mitk::PlanarBezierCurve::GetControlPointForPolylinePoint(int indexOfPolylinePoint, int polyLineIndex) const
98 {
99  mitk::PlanarFigure::PolyLineType polyLine = GetPolyLine(polyLineIndex);
100 
101  if (indexOfPolylinePoint < 0 || indexOfPolylinePoint > static_cast<int>(polyLine.size()))
102  return -1;
103 
104  mitk::PlanarFigure::ControlPointListType::const_iterator elem;
105  auto first = m_ControlPoints.cbegin();
106  auto end = m_ControlPoints.cend();
107 
108  mitk::PlanarFigure::PolyLineType::const_iterator polyLineIter;
109  auto polyLineEnd = polyLine.cend();
110  auto polyLineStart = polyLine.cbegin();
111  polyLineStart += indexOfPolylinePoint;
112 
113  for (polyLineIter = polyLineStart; polyLineIter != polyLineEnd; ++polyLineIter)
114  {
115  elem = std::find(first, end, *polyLineIter);
116 
117  if (elem != end)
118  return std::distance(first, elem);
119  }
120 
121  return GetNumberOfControlPoints();
122 }
123 
125 {
127 }
128 
130 {
131  return 2;
132 }
133 
134 bool mitk::PlanarBezierCurve::IsHelperToBePainted(unsigned int index) const
135 {
136  return index == 0 && m_ControlPoints.size() > 2;
137 }
138 
140 {
141  const auto *otherBezierCurve = dynamic_cast<const mitk::PlanarBezierCurve *>(&other);
142  if (otherBezierCurve)
143  {
144  if (this->m_NumberOfSegments != otherBezierCurve->m_NumberOfSegments)
145  return false;
146  if (this->m_DeCasteljauPoints != otherBezierCurve->m_DeCasteljauPoints)
147  return false;
148  return Superclass::Equals(other);
149  }
150  else
151  {
152  return false;
153  }
154 }
void EvaluateFeaturesInternal() override
Calculates quantities of all features of this planar figure. Must be implemented in sub-classes...
double ScalarType
void GenerateHelperPolyLine(double, unsigned int) override
Generates the poly-lines that should be drawn the same size regardless of zoom. Must be implemented i...
void ResetNumberOfControlPoints(int numberOfControlPoints)
Set the initial number of control points of the planar figure.
bool IsHelperToBePainted(unsigned int index) const override
Returns whether a helper polyline should be painted or not.
const PolyLineType GetPolyLine(unsigned int index)
Returns the polyline representing the planar figure (for rendering, measurements, etc...
itk::DataObject Superclass
Definition: mitkBaseData.h:41
unsigned int GetMinimumNumberOfControlPoints() const override
Returns the minimum number of control points needed to represent this figure.
unsigned int GetMaximumNumberOfControlPoints() const override
Returns the maximum number of control points allowed for this figure (e.g. 3 for triangles).
unsigned int GetNumberOfControlPoints() const
Returns the current number of 2D control points defining this figure.
virtual bool IsPlaced() const
True if the planar figure has been placed (and can be displayed/interacted with). ...
void SetQuantity(unsigned int index, double quantity)
ControlPointListType m_ControlPoints
void SetNumberOfHelperPolyLines(unsigned int numberOfHelperPolyLines)
defines the number of HelperPolyLines that will be available
static T max(T x, T y)
Definition: svm.cpp:56
void AppendPointToPolyLine(unsigned int index, PolyLineElement element)
Append a point to the PolyLine # index.
const unsigned int FEATURE_ID_LENGTH
void GeneratePolyLine() override
Generates the poly-line representation of the planar figure. Must be implemented in sub-classes...
int GetControlPointForPolylinePoint(int indexOfPolylinePoint, int polyLineIndex) const override
Returns the id of the control-point that corresponds to the given polyline-point. ...
unsigned int GetNumberOfSegments() const
bool Equals(const mitk::PlanarFigure &other) const override
Compare two PlanarFigure objects Note: all subclasses have to implement the method on their own...
void SetNumberOfPolyLines(unsigned int numberOfPolyLines)
defines the number of PolyLines that will be available
Base-class for geometric planar (2D) figures, such as lines, circles, rectangles, polygons...
void AppendPointToHelperPolyLine(unsigned int index, PolyLineElement element)
Append a point to the HelperPolyLine # index.
void SetNumberOfSegments(unsigned int numSegments)
void ClearHelperPolyLines()
clears the list of HelperPolyLines. Call before re-calculating a new HelperPolyline.
std::vector< PolyLineElement > PolyLineType
std::vector< PolyLineType > m_PolyLines
void ClearPolyLines()
clears the list of PolyLines. Call before re-calculating a new Polyline.