23 : FEATURE_ID_MAJOR_AXIS(
Superclass::AddFeature(
"Major Axis",
"mm")),
24 FEATURE_ID_MINOR_AXIS(
Superclass::AddFeature(
"Minor Axis",
"mm")),
25 FEATURE_ID_THICKNESS(
Superclass::AddFeature(
"Thickness",
"mm")),
26 m_NumberOfSegments(64),
27 m_ConstrainCircle(true),
28 m_ConstrainThickness(true)
37 if (index == 2 && !m_ConstrainCircle)
39 const Point2D centerPoint = this->GetControlPoint(0);
40 const Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;
43 minorDirection[0] = outerMajorVector[1];
44 minorDirection[1] = -outerMajorVector[0];
45 minorDirection.Normalize();
47 const double outerMajorRadius = outerMajorVector.GetNorm();
48 const double innerMajorRadius = (this->GetControlPoint(3) - centerPoint).GetNorm();
50 std::max(outerMajorRadius - innerMajorRadius,
std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
52 return centerPoint + minorDirection * radius;
54 else if (index == 3 && !m_ConstrainThickness)
56 const Point2D centerPoint = this->GetControlPoint(0);
57 Vector2D outerMajorVector = this->GetControlPoint(1) - centerPoint;
59 const double outerMajorRadius = outerMajorVector.GetNorm();
60 const double outerMinorRadius = (this->GetControlPoint(2) - centerPoint).GetNorm();
62 std::max(outerMajorRadius - outerMinorRadius,
std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
64 outerMajorVector.Normalize();
66 return centerPoint - outerMajorVector * radius;
74 const Point2D centerPoint = this->GetControlPoint(0);
75 const ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(1));
77 this->SetQuantity(FEATURE_ID_MAJOR_AXIS, 2 * outerMajorRadius);
78 this->SetQuantity(FEATURE_ID_MINOR_AXIS, 2 * centerPoint.EuclideanDistanceTo(this->GetControlPoint(2)));
79 this->SetQuantity(FEATURE_ID_THICKNESS, outerMajorRadius - centerPoint.EuclideanDistanceTo(this->GetControlPoint(3)));
88 this->ClearPolyLines();
90 const Point2D centerPoint = this->GetControlPoint(0);
91 const Point2D outerMajorPoint = this->GetControlPoint(1);
93 Vector2D direction = outerMajorPoint - centerPoint;
94 direction.Normalize();
96 const ScalarType deltaAngle = vnl_math::pi / (m_NumberOfSegments / 2);
99 int end = m_NumberOfSegments;
101 if (direction[1] < 0.0)
103 direction[0] = -direction[0];
104 end = m_NumberOfSegments / 2;
108 vnl_matrix_fixed<mitk::ScalarType, 2, 2>
rotation;
109 rotation[1][0] = std::sin(std::acos(direction[0]));
110 rotation[0][0] = direction[0];
111 rotation[1][1] = direction[0];
112 rotation[0][1] = -rotation[1][0];
114 const ScalarType outerMajorRadius = centerPoint.EuclideanDistanceTo(outerMajorPoint);
115 const ScalarType outerMinorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
116 const ScalarType innerMajorRadius = centerPoint.EuclideanDistanceTo(this->GetControlPoint(3));
117 const ScalarType innerMinorRadius = innerMajorRadius - (outerMajorRadius - outerMinorRadius);
122 vnl_vector_fixed<mitk::ScalarType, 2> vector;
125 for (
int i = start; i < end; ++i)
127 angle = i * deltaAngle;
128 cosAngle = std::cos(angle);
129 sinAngle = std::sin(angle);
131 vector[0] = outerMajorRadius * cosAngle;
132 vector[1] = outerMinorRadius * sinAngle;
133 vector = rotation * vector;
135 point[0] = centerPoint[0] + vector[0];
136 point[1] = centerPoint[1] + vector[1];
138 this->AppendPointToPolyLine(0, point);
140 vector[0] = innerMajorRadius * cosAngle;
141 vector[1] = innerMinorRadius * sinAngle;
142 vector = rotation * vector;
144 point[0] = centerPoint[0] + vector[0];
145 point[1] = centerPoint[1] + vector[1];
147 this->AppendPointToPolyLine(1, point);
153 return m_NumberOfSegments;
158 m_NumberOfSegments =
std::max(4U, numSegments);
160 if (this->IsPlaced())
162 this->GeneratePolyLine();
183 const Point2D centerPoint = this->GetControlPoint(0);
184 const Vector2D vector = point - centerPoint;
186 Superclass::SetControlPoint(0, point, createIfDoesNotExist);
187 Superclass::SetControlPoint(1, this->GetControlPoint(1) + vector, createIfDoesNotExist);
188 Superclass::SetControlPoint(2, this->GetControlPoint(2) + vector, createIfDoesNotExist);
189 Superclass::SetControlPoint(3, this->GetControlPoint(3) + vector, createIfDoesNotExist);
196 const Vector2D vector = point - this->GetControlPoint(1);
198 Superclass::SetControlPoint(1, point, createIfDoesNotExist);
200 const Point2D centerPoint = this->GetControlPoint(0);
201 const Vector2D outerMajorVector = point - centerPoint;
204 outerMinorVector[0] = outerMajorVector[1];
205 outerMinorVector[1] = -outerMajorVector[0];
207 if (!m_ConstrainCircle)
209 outerMinorVector.Normalize();
210 outerMinorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
213 Superclass::SetControlPoint(2, centerPoint + outerMinorVector, createIfDoesNotExist);
215 Vector2D innerMajorVector = outerMajorVector;
217 if (!m_ConstrainThickness)
219 innerMajorVector.Normalize();
220 innerMajorVector *= centerPoint.EuclideanDistanceTo(this->GetControlPoint(3) - vector);
223 Superclass::SetControlPoint(3, centerPoint - innerMajorVector, createIfDoesNotExist);
230 m_ConstrainCircle =
false;
231 Superclass::SetControlPoint(2, point, createIfDoesNotExist);
238 m_ConstrainThickness =
false;
239 Superclass::SetControlPoint(3, point, createIfDoesNotExist);
254 if (otherDoubleEllipse)
256 if (this->m_ConstrainCircle != otherDoubleEllipse->m_ConstrainCircle)
258 if (this->m_ConstrainThickness != otherDoubleEllipse->m_ConstrainThickness)
260 if (this->m_NumberOfSegments != otherDoubleEllipse->m_NumberOfSegments)
262 return Superclass::Equals(other);
Point< ScalarType, 2 > Point2D
virtual bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=true) override
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...
virtual unsigned int GetMinimumNumberOfControlPoints() const override
Returns the minimum number of control points needed to represent this figure.
void SetNumberOfSegments(unsigned int numSegments)
itk::DataObject Superclass
void SetProperty(const char *propertyKey, BaseProperty *property)
Vector< ScalarType, 2 > Vector2D
virtual mitkCloneMacro(Self) virtual mitk void EvaluateFeaturesInternal() override
Calculates quantities of all features of this planar figure. Must be implemented in sub-classes...
virtual unsigned int GetMaximumNumberOfControlPoints() const override
Returns the maximum number of control points allowed for this figure (e.g. 3 for triangles).
unsigned int GetNumberOfSegments() const
virtual void GeneratePolyLine() override
Generates the poly-line representation of the planar figure. Must be implemented in sub-classes...
virtual bool Equals(const mitk::PlanarFigure &other) const override
Compare two PlanarFigure objects Note: all subclasses have to implement the method on their own...