Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkPlanarCircle.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 "mitkPlanarCircle.h"
18 #include "mitkPlaneGeometry.h"
19 
20 #include "mitkProperties.h"
21 
23  : FEATURE_ID_RADIUS(this->AddFeature("Radius", "mm")),
24  FEATURE_ID_DIAMETER(this->AddFeature("Diameter", "mm")),
25  FEATURE_ID_AREA(this->AddFeature("Area", "mm2")),
26  m_MinRadius(0),
27  m_MaxRadius(100),
28  m_MinMaxRadiusContraintsActive(false)
29 {
30  // Circle has two control points
32  this->SetNumberOfPolyLines(1);
33  this->SetProperty("closed", mitk::BoolProperty::New(true));
34 }
35 
36 bool mitk::PlanarCircle::SetControlPoint(unsigned int index, const Point2D &point, bool /*createIfDoesNotExist*/)
37 {
38  // moving center point
39  if (index == 0)
40  {
41  const Point2D &centerPoint = GetControlPoint(0);
42  Point2D boundaryPoint = GetControlPoint(1);
43  const vnl_vector<ScalarType> vec = (point.GetVnlVector() - centerPoint.GetVnlVector());
44 
45  boundaryPoint[0] += vec[0];
46  boundaryPoint[1] += vec[1];
48  PlanarFigure::SetControlPoint(1, boundaryPoint);
49  return true;
50  }
51  else if (index == 1)
52  {
53  PlanarFigure::SetControlPoint(index, point);
54  return true;
55  }
56  return false;
57 }
58 
60 {
61  if (this->GetPlaneGeometry() == nullptr)
62  {
63  return point;
64  }
65 
66  Point2D indexPoint;
67  this->GetPlaneGeometry()->WorldToIndex(point, indexPoint);
68 
69  const BoundingBox::BoundsArrayType bounds = this->GetPlaneGeometry()->GetBounds();
70  if (indexPoint[0] < bounds[0])
71  {
72  indexPoint[0] = bounds[0];
73  }
74  if (indexPoint[0] > bounds[1])
75  {
76  indexPoint[0] = bounds[1];
77  }
78  if (indexPoint[1] < bounds[2])
79  {
80  indexPoint[1] = bounds[2];
81  }
82  if (indexPoint[1] > bounds[3])
83  {
84  indexPoint[1] = bounds[3];
85  }
86 
87  Point2D constrainedPoint;
88  this->GetPlaneGeometry()->IndexToWorld(indexPoint, constrainedPoint);
89 
90  if (m_MinMaxRadiusContraintsActive)
91  {
92  if (index != 0)
93  {
94  const Point2D &centerPoint = this->GetControlPoint(0);
95  const double euclideanDinstanceFromCenterToPoint1 = centerPoint.EuclideanDistanceTo(point);
96 
97  Vector2D vectorProjectedPoint = point - centerPoint;
98  vectorProjectedPoint.Normalize();
99 
100  if (euclideanDinstanceFromCenterToPoint1 > m_MaxRadius)
101  {
102  vectorProjectedPoint *= m_MaxRadius;
103  constrainedPoint = centerPoint;
104  constrainedPoint += vectorProjectedPoint;
105  }
106  else if (euclideanDinstanceFromCenterToPoint1 < m_MinRadius)
107  {
108  vectorProjectedPoint *= m_MinRadius;
109  constrainedPoint = centerPoint;
110  constrainedPoint += vectorProjectedPoint;
111  }
112  }
113  }
114 
115  return constrainedPoint;
116 }
117 
119 {
120  // TODO: start circle at specified boundary point...
121 
122  // clear the PolyLine-Contrainer, it will be reconstructed soon enough...
123  this->ClearPolyLines();
124 
125  const Point2D &centerPoint = GetControlPoint(0);
126  const Point2D &boundaryPoint = GetControlPoint(1);
127 
128  const double radius = centerPoint.EuclideanDistanceTo(boundaryPoint);
129 
130  // Generate poly-line with 64 segments
131  for (int t = 0; t < 64; ++t)
132  {
133  const double alpha = (double)t * vnl_math::pi / 32.0;
134 
135  // construct the new polyline point ...
136  Point2D polyLinePoint;
137  polyLinePoint[0] = centerPoint[0] + radius * cos(alpha);
138  polyLinePoint[1] = centerPoint[1] + radius * sin(alpha);
139 
140  // ... and append it to the PolyLine.
141  // No extending supported here, so we can set the index of the PolyLineElement to '0'
142  this->AppendPointToPolyLine(0, polyLinePoint);
143  }
144 }
145 
146 void mitk::PlanarCircle::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
147 {
148  // A circle does not require a helper object
149 }
150 
152 {
153  // Calculate circle radius and area
154  const Point3D &p0 = this->GetWorldControlPoint(0);
155  const Point3D &p1 = this->GetWorldControlPoint(1);
156 
157  const double radius = p0.EuclideanDistanceTo(p1);
158  const double area = vnl_math::pi * radius * radius;
159 
160  this->SetQuantity(FEATURE_ID_RADIUS, radius);
161  this->SetQuantity(FEATURE_ID_DIAMETER, 2 * radius);
162  this->SetQuantity(FEATURE_ID_AREA, area);
163 }
164 
165 void mitk::PlanarCircle::PrintSelf(std::ostream &os, itk::Indent indent) const
166 {
167  Superclass::PrintSelf(os, indent);
168 }
169 
171 {
172  if (m_SelectedControlPoint < 0)
173  {
174  m_SelectedControlPoint = 1;
175  }
176 
177  return this->SetControlPoint(m_SelectedControlPoint, point, false);
178 }
179 
180 bool mitk::PlanarCircle::Equals(const PlanarFigure &other) const
181 {
182  const mitk::PlanarCircle *otherCircle = dynamic_cast<const mitk::PlanarCircle *>(&other);
183  if (otherCircle)
184  {
185  return Superclass::Equals(other);
186  }
187  else
188  {
189  return false;
190  }
191 }
virtual Point2D ApplyControlPointConstraints(unsigned int index, const Point2D &point) override
Spatially constrain control points of second (orthogonal) line.
void ResetNumberOfControlPoints(int numberOfControlPoints)
Set the initial number of control points of the planar figure.
virtual void GeneratePolyLine() override
Generates the poly-line representation of the planar figure.
bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=false) override
Place figure in its minimal configuration (a point at least) onto the given 2D geometry.
virtual bool SetCurrentControlPoint(const Point2D &point) override
static Pointer New()
void SetProperty(const char *propertyKey, BaseProperty *property)
virtual void EvaluateFeaturesInternal() override
Calculates feature quantities of the planar figure.
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const override
void SetNumberOfPolyLines(unsigned int numberOfPolyLines)
defines the number of PolyLines that will be available
virtual bool Equals(const mitk::PlanarFigure &other) const override
Compare two PlanarFigure objects Note: all subclasses have to implement the method on their own...
virtual bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=false)
Base-class for geometric planar (2D) figures, such as lines, circles, rectangles, polygons...
Implementation of PlanarFigure representing a circle through two control points.
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) override
Generates the poly-lines that should be drawn the same size regardless of zoom.
BoundingBoxType::BoundsArrayType BoundsArrayType