Medical Imaging Interaction Toolkit  2016.11.0
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,
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 #include "mitkPlanarBezierCurve.h"
18 #include <mitkProperties.h>
19 
20 #include <limits>
21 
23  : FEATURE_ID_LENGTH(Superclass::AddFeature("Length", "mm")), m_NumberOfSegments(100)
24 {
26  this->SetNumberOfPolyLines(1);
28 }
29 
31 {
32  double length = 0.0;
33 
34  for (unsigned int i = 0; i < m_NumberOfSegments; ++i)
35  length += static_cast<Point2D>(m_PolyLines[0][i]).EuclideanDistanceTo(static_cast<Point2D>(m_PolyLines[0][i + 1]));
36 
37  this->SetQuantity(FEATURE_ID_LENGTH, length);
38 }
39 
41 {
42  return m_NumberOfSegments;
43 }
44 
45 void mitk::PlanarBezierCurve::SetNumberOfSegments(unsigned int numSegments)
46 {
47  m_NumberOfSegments = std::max(1U, numSegments);
48 
49  if (this->IsPlaced())
50  {
51  this->GeneratePolyLine();
52  this->Modified();
53  }
54 }
55 
57 {
58  this->ClearHelperPolyLines();
59 
60  unsigned int numHelperPolyLinePoints = m_ControlPoints.size();
61 
62  for (unsigned int i = 0; i < numHelperPolyLinePoints; ++i)
63  this->AppendPointToHelperPolyLine(0, m_ControlPoints[i]);
64 }
65 
67 {
68  this->ClearPolyLines();
69 
70  const unsigned int numPolyLinePoints = m_NumberOfSegments + 1;
71 
72  for (unsigned int i = 0; i < numPolyLinePoints; ++i)
73  this->AppendPointToPolyLine(0, this->ComputeDeCasteljauPoint(i / static_cast<ScalarType>(m_NumberOfSegments)));
74 }
75 
76 mitk::Point2D mitk::PlanarBezierCurve::ComputeDeCasteljauPoint(mitk::ScalarType t)
77 {
78  unsigned int n = m_ControlPoints.size() - 1;
79 
80  if (m_DeCasteljauPoints.size() != n)
81  m_DeCasteljauPoints.resize(n);
82 
83  for (unsigned int i = 0; i < n; ++i)
84  {
85  m_DeCasteljauPoints[i][0] = (1 - t) * m_ControlPoints[i][0] + t * m_ControlPoints[i + 1][0];
86  m_DeCasteljauPoints[i][1] = (1 - t) * m_ControlPoints[i][1] + t * m_ControlPoints[i + 1][1];
87  }
88 
89  for (--n; n > 0; --n)
90  {
91  for (unsigned int i = 0; i < n; ++i)
92  {
93  m_DeCasteljauPoints[i][0] = (1 - t) * m_DeCasteljauPoints[i][0] + t * m_DeCasteljauPoints[i + 1][0];
94  m_DeCasteljauPoints[i][1] = (1 - t) * m_DeCasteljauPoints[i][1] + t * m_DeCasteljauPoints[i + 1][1];
95  }
96  }
97 
98  return m_DeCasteljauPoints[0];
99 }
100 
101 int mitk::PlanarBezierCurve::GetControlPointForPolylinePoint(int indexOfPolylinePoint, int polyLineIndex) const
102 {
103  mitk::PlanarFigure::PolyLineType polyLine = GetPolyLine(polyLineIndex);
104 
105  if (indexOfPolylinePoint < 0 || indexOfPolylinePoint > static_cast<int>(polyLine.size()))
106  return -1;
107 
108  mitk::PlanarFigure::ControlPointListType::const_iterator elem;
109  mitk::PlanarFigure::ControlPointListType::const_iterator first = m_ControlPoints.cbegin();
110  mitk::PlanarFigure::ControlPointListType::const_iterator end = m_ControlPoints.cend();
111 
112  mitk::PlanarFigure::PolyLineType::const_iterator polyLineIter;
113  mitk::PlanarFigure::PolyLineType::const_iterator polyLineEnd = polyLine.cend();
114  mitk::PlanarFigure::PolyLineType::const_iterator polyLineStart = polyLine.cbegin();
115  polyLineStart += indexOfPolylinePoint;
116 
117  for (polyLineIter = polyLineStart; polyLineIter != polyLineEnd; ++polyLineIter)
118  {
119  elem = std::find(first, end, *polyLineIter);
120 
121  if (elem != end)
122  return std::distance(first, elem);
123  }
124 
125  return GetNumberOfControlPoints();
126 }
127 
129 {
131 }
132 
134 {
135  return 2;
136 }
137 
138 bool mitk::PlanarBezierCurve::IsHelperToBePainted(unsigned int index) const
139 {
140  return index == 0 && m_ControlPoints.size() > 2;
141 }
142 
144 {
145  const mitk::PlanarBezierCurve *otherBezierCurve = dynamic_cast<const mitk::PlanarBezierCurve *>(&other);
146  if (otherBezierCurve)
147  {
148  if (this->m_NumberOfSegments != otherBezierCurve->m_NumberOfSegments)
149  return false;
150  if (this->m_DeCasteljauPoints != otherBezierCurve->m_DeCasteljauPoints)
151  return false;
152  return Superclass::Equals(other);
153  }
154  else
155  {
156  return false;
157  }
158 }
double ScalarType
virtual 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.
virtual bool IsHelperToBePainted(unsigned int index) const override
Returns whether a helper polyline should be painted or not.
unsigned int GetNumberOfSegments() const
itk::DataObject Superclass
Definition: mitkBaseData.h:42
virtual unsigned int GetMinimumNumberOfControlPoints() const override
Returns the minimum number of control points needed to represent this figure.
virtual unsigned int GetMaximumNumberOfControlPoints() const override
Returns the maximum number of control points allowed for this figure (e.g. 3 for triangles).
void SetNumberOfHelperPolyLines(unsigned int numberOfHelperPolyLines)
defines the number of HelperPolyLines that will be available
virtual void EvaluateFeaturesInternal()=0
Calculates quantities of all features of this planar figure. Must be implemented in sub-classes...
static T max(T x, T y)
Definition: svm.cpp:70
virtual 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. ...
virtual 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 SetNumberOfSegments(unsigned int numSegments)
std::vector< PolyLineElement > PolyLineType