19 : FEATURE_ID_MAJOR_AXIS(
Superclass::AddFeature(
"Major Axis",
"mm")),
20 FEATURE_ID_MINOR_AXIS(
Superclass::AddFeature(
"Minor Axis",
"mm")),
21 FEATURE_ID_THICKNESS(
Superclass::AddFeature(
"Thickness",
"mm")),
22 m_NumberOfSegments(64),
23 m_ConstrainCircle(true),
24 m_ConstrainThickness(true)
35 m_NumberOfSegments(64),
36 m_ConstrainCircle(true),
37 m_ConstrainThickness(true),
38 m_FixedRadius(fixedRadius),
39 m_FixedThickness(fixedThickness),
46 if (fixedThickness>fixedRadius)
48 mitkThrow() <<
"Invalid constructor of fixed sized double ellipses. Thickness (" << fixedThickness <<
") is greater than the radius (" << fixedRadius <<
")";
54 if (index == 2 && !m_ConstrainCircle)
60 minorDirection[0] = outerMajorVector[1];
61 minorDirection[1] = -outerMajorVector[0];
62 minorDirection.Normalize();
64 const double outerMajorRadius = outerMajorVector.GetNorm();
67 std::max(outerMajorRadius - innerMajorRadius,
std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
69 return centerPoint + minorDirection * radius;
71 else if (index == 3 && !m_ConstrainThickness)
76 const double outerMajorRadius = outerMajorVector.GetNorm();
79 std::max(outerMajorRadius - outerMinorRadius,
std::min(centerPoint.EuclideanDistanceTo(point), outerMajorRadius));
81 outerMajorVector.Normalize();
83 return centerPoint - outerMajorVector * radius;
92 const ScalarType outerMajorRadius = (m_SizeIsFixed)? m_FixedRadius : centerPoint.EuclideanDistanceTo(this->GetControlPoint(
CP_OUTER_MAJOR_AXIS));
93 const ScalarType outerMinorRadius = (m_SizeIsFixed)? m_FixedRadius : centerPoint.EuclideanDistanceTo(this->GetControlPoint(
CP_OUTER_MINOR_AXIS));
94 const ScalarType thickness = (m_SizeIsFixed)? m_FixedThickness : outerMajorRadius - centerPoint.EuclideanDistanceTo(this->GetControlPoint(
CP_INNER_MAJOR_AXIS));
116 direction.Normalize();
119 const ScalarType deltaAngle = vnl_math::pi / (m_NumberOfSegments / 2);
122 int end = m_NumberOfSegments;
124 if (direction[1] < 0.0)
126 direction[0] = -direction[0];
127 end = m_NumberOfSegments / 2;
131 vnl_matrix_fixed<mitk::ScalarType, 2, 2>
rotation;
132 rotation[1][0] = std::sin(std::acos(direction[0]));
133 rotation[0][0] = direction[0];
134 rotation[1][1] = direction[0];
135 rotation[0][1] = -rotation[1][0];
137 const ScalarType outerMajorRadius = (m_SizeIsFixed) ? m_FixedRadius : centerPoint.EuclideanDistanceTo(this->GetControlPoint(
CP_OUTER_MAJOR_AXIS));
138 const ScalarType outerMinorRadius = (m_SizeIsFixed) ? m_FixedRadius : centerPoint.EuclideanDistanceTo(this->GetControlPoint(
CP_OUTER_MINOR_AXIS));
140 const ScalarType innerMinorRadius = (m_SizeIsFixed) ? (m_FixedRadius-m_FixedThickness) : innerMajorRadius - (outerMajorRadius - outerMinorRadius);
145 vnl_vector_fixed<mitk::ScalarType, 2> vector;
148 for (
int i = start; i < end; ++i)
150 angle = i * deltaAngle;
151 cosAngle = std::cos(angle);
152 sinAngle = std::sin(angle);
154 vector[0] = outerMajorRadius * cosAngle;
155 vector[1] = outerMinorRadius * sinAngle;
156 vector = rotation * vector;
158 point[0] = centerPoint[0] + vector[0];
159 point[1] = centerPoint[1] + vector[1];
163 vector[0] = innerMajorRadius * cosAngle;
164 vector[1] = innerMinorRadius * sinAngle;
165 vector = rotation * vector;
167 point[0] = centerPoint[0] + vector[0];
168 point[1] = centerPoint[1] + vector[1];
176 return m_NumberOfSegments;
181 m_NumberOfSegments =
std::max(4U, numSegments);
192 return (m_SizeIsFixed)? 1 : 4;
197 return (m_SizeIsFixed)? 1 : 4;
207 const Vector2D vector = point - centerPoint;
209 Superclass::SetControlPoint(0, point, createIfDoesNotExist);
224 Superclass::SetControlPoint(1, point, createIfDoesNotExist);
227 const Vector2D outerMajorVector = point - centerPoint;
230 outerMinorVector[0] = outerMajorVector[1];
231 outerMinorVector[1] = -outerMajorVector[0];
233 if (!m_ConstrainCircle)
235 outerMinorVector.Normalize();
239 Superclass::SetControlPoint(2, centerPoint + outerMinorVector, createIfDoesNotExist);
241 Vector2D innerMajorVector = outerMajorVector;
243 if (!m_ConstrainThickness)
245 innerMajorVector.Normalize();
249 Superclass::SetControlPoint(3, centerPoint - innerMajorVector, createIfDoesNotExist);
256 m_ConstrainCircle =
false;
257 Superclass::SetControlPoint(2, point, createIfDoesNotExist);
264 m_ConstrainThickness =
false;
265 Superclass::SetControlPoint(3, point, createIfDoesNotExist);
280 if (otherDoubleEllipse)
282 if (this->m_ConstrainCircle != otherDoubleEllipse->m_ConstrainCircle)
284 if (this->m_ConstrainThickness != otherDoubleEllipse->m_ConstrainThickness)
286 if (this->m_NumberOfSegments != otherDoubleEllipse->m_NumberOfSegments)
288 return Superclass::Equals(other);
bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=true) override
void GenerateHelperPolyLine(double, unsigned int) override
Generates the poly-lines that should be drawn the same size regardless of zoom. Must be implemented i...
static const unsigned int CP_OUTER_MAJOR_AXIS
unsigned int GetMinimumNumberOfControlPoints() const override
Returns the minimum number of control points needed to represent this figure.
void SetNumberOfSegments(unsigned int numSegments)
static const unsigned int CP_CENTER
static const unsigned int CP_OUTER_MINOR_AXIS
Planar representing a double ellipse. The double ellipse is either represented by 4 control points (c...
itk::DataObject Superclass
void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName="", bool fallBackOnDefaultContext=false) override
Add new or change existent property.
const unsigned int FEATURE_ID_THICKNESS
const unsigned int FEATURE_ID_MAJOR_AXIS
static const unsigned int CP_INNER_MAJOR_AXIS
void EvaluateFeaturesInternal() override
Calculates quantities of all features of this planar figure. Must be implemented in sub-classes...
unsigned int GetMaximumNumberOfControlPoints() const override
Returns the maximum number of control points allowed for this figure (e.g. 3 for triangles).
const unsigned int FEATURE_ID_MINOR_AXIS
void GeneratePolyLine() override
Generates the poly-line representation of the planar figure. Must be implemented in sub-classes...
bool Equals(const mitk::PlanarFigure &other) const override
Compare two PlanarFigure objects Note: all subclasses have to implement the method on their own...
mitk::Point2D ApplyControlPointConstraints(unsigned int index, const Point2D &point) override
Allow sub-classes to apply constraints on control points.
unsigned int GetNumberOfSegments() const