23 #define _USE_MATH_DEFINES
27 : FEATURE_ID_MAJOR_AXIS(
Superclass::AddFeature(
"Major Axis",
"mm")),
28 FEATURE_ID_MINOR_AXIS(
Superclass::AddFeature(
"Minor Axis",
"mm")),
29 FEATURE_ID_AREA(
Superclass::AddFeature(
"Area",
"mm2")),
32 m_MinMaxRadiusContraintsActive(false),
45 const Point2D ¢erPoint = GetControlPoint(0);
46 Point2D boundaryPoint1 = GetControlPoint(1);
47 Point2D boundaryPoint2 = GetControlPoint(2);
48 Point2D boundaryPoint3 = GetControlPoint(3);
49 const vnl_vector<ScalarType> vec = (point.GetVnlVector() - centerPoint.GetVnlVector());
51 boundaryPoint1[0] += vec[0];
52 boundaryPoint1[1] += vec[1];
53 boundaryPoint2[0] += vec[0];
54 boundaryPoint2[1] += vec[1];
55 boundaryPoint3[0] += vec[0];
56 boundaryPoint3[1] += vec[1];
66 int otherIndex = index + 1;
70 const Point2D ¢erPoint = GetControlPoint(0);
71 Point2D otherPoint = GetControlPoint(otherIndex);
72 Point2D point3 = GetControlPoint(3);
74 const Vector2D vec1 = point - centerPoint;
77 if (index == 1 && m_TreatAsCircle)
79 const float x = vec1[0];
88 otherPoint = centerPoint + vec2;
90 const float r = centerPoint.EuclideanDistanceTo(otherPoint);
93 const Point2D p3 = this->GetControlPoint(3);
95 vec3[0] = p3[0] - centerPoint[0];
96 vec3[1] = p3[1] - centerPoint[1];
97 if (vec3[0] != 0 || vec3[1] != 0)
107 point3 = centerPoint + vec3;
110 else if (vec1.GetNorm() > 0)
112 const float r = centerPoint.EuclideanDistanceTo(otherPoint);
113 const float x = vec1[0];
125 if (vec2.GetNorm() > 0)
127 otherPoint = centerPoint + vec2;
132 Vector2D vec3 = point3 - centerPoint;
134 const double r1 = centerPoint.EuclideanDistanceTo(GetControlPoint(1));
135 const double r2 = centerPoint.EuclideanDistanceTo(GetControlPoint(2));
139 m_TreatAsCircle =
false;
145 const Point2D centerPoint = GetControlPoint(0);
146 Vector2D vec3 = point - centerPoint;
148 const double r1 = centerPoint.EuclideanDistanceTo(GetControlPoint(1));
149 const double r2 = centerPoint.EuclideanDistanceTo(GetControlPoint(2));
152 m_TreatAsCircle =
false;
161 m_SelectedControlPoint = 1;
169 this->GetPlaneGeometry()->WorldToIndex(point, indexPoint);
172 if (indexPoint[0] < bounds[0])
174 indexPoint[0] = bounds[0];
176 if (indexPoint[0] > bounds[1])
178 indexPoint[0] = bounds[1];
180 if (indexPoint[1] < bounds[2])
182 indexPoint[1] = bounds[2];
184 if (indexPoint[1] > bounds[3])
186 indexPoint[1] = bounds[3];
190 this->GetPlaneGeometry()->IndexToWorld(indexPoint, constrainedPoint);
192 if (m_MinMaxRadiusContraintsActive)
196 const Point2D ¢erPoint = this->GetControlPoint(0);
197 const double euclideanDinstanceFromCenterToPoint1 = centerPoint.EuclideanDistanceTo(point);
199 Vector2D vectorProjectedPoint = point - centerPoint;
200 vectorProjectedPoint.Normalize();
202 if (euclideanDinstanceFromCenterToPoint1 > m_MaxRadius)
204 vectorProjectedPoint *= m_MaxRadius;
205 constrainedPoint = centerPoint;
206 constrainedPoint += vectorProjectedPoint;
208 else if (euclideanDinstanceFromCenterToPoint1 < m_MinRadius)
210 vectorProjectedPoint *= m_MinRadius;
211 constrainedPoint = centerPoint;
212 constrainedPoint += vectorProjectedPoint;
217 return constrainedPoint;
223 this->ClearPolyLines();
225 const Point2D ¢erPoint = GetControlPoint(0);
226 const Point2D &boundaryPoint1 = GetControlPoint(1);
227 const Point2D &boundaryPoint2 = GetControlPoint(2);
229 Vector2D dir = boundaryPoint1 - centerPoint;
231 vnl_matrix_fixed<float, 2, 2> rot;
244 rot[1][1] = rot[0][0];
245 rot[1][0] = sin(acos(rot[0][0]));
246 rot[0][1] = -rot[1][0];
248 const double radius1 = centerPoint.EuclideanDistanceTo(boundaryPoint1);
249 const double radius2 = centerPoint.EuclideanDistanceTo(boundaryPoint2);
252 for (
int t = start; t < end; ++t)
254 const double alpha = (double)t * vnl_math::pi / 32.0;
257 vnl_vector_fixed<float, 2> vec;
258 vec[0] = radius1 * cos(alpha);
259 vec[1] = radius2 * sin(alpha);
263 polyLinePoint[0] = centerPoint[0] + vec[0];
264 polyLinePoint[1] = centerPoint[1] + vec[1];
268 this->AppendPointToPolyLine(0, polyLinePoint);
271 this->AppendPointToPolyLine(1, centerPoint);
272 this->AppendPointToPolyLine(1, this->GetControlPoint(3));
282 const Point2D centerPoint = this->GetControlPoint(0);
284 const auto longAxisLength = centerPoint.EuclideanDistanceTo(this->GetControlPoint(1));
285 const auto shortAxisLength = centerPoint.EuclideanDistanceTo(this->GetControlPoint(2));
287 this->SetQuantity(FEATURE_ID_MAJOR_AXIS, 2 * longAxisLength);
288 this->SetQuantity(FEATURE_ID_MINOR_AXIS, 2 * shortAxisLength);
289 this->SetQuantity(FEATURE_ID_AREA, longAxisLength * shortAxisLength *
M_PI);
294 Superclass::PrintSelf(os, indent);
305 return Superclass::Equals(other);
bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=true) override
Implementation of PlanarFigure representing a circle through two control points.
virtual void PlaceFigure(const Point2D &point) override
Place figure in its minimal configuration (a point at least) onto the given 2D geometry.
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override
itk::DataObject Superclass
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 SetProperty(const char *propertyKey, BaseProperty *property)
virtual void EvaluateFeaturesInternal() override
Calculates feature quantities of the planar figure.
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) override
Generates the poly-lines that should be drawn the same size regardless of zoom.
virtual Point2D ApplyControlPointConstraints(unsigned int index, const Point2D &point) override
Spatially constrain control points of second (orthogonal) line.
virtual void GeneratePolyLine() override
Generates the poly-line representation of the planar figure.
BoundingBoxType::BoundsArrayType BoundsArrayType