Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPlanarRectangle.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkProperties.h"
14 
15 #include "mitkPlanarRectangle.h"
16 #include "mitkPlaneGeometry.h"
17 
19  : FEATURE_ID_CIRCUMFERENCE(this->AddFeature("Circumference", "mm")), FEATURE_ID_AREA(this->AddFeature("Area", "mm2"))
20 {
21  // Rectangle has four control points
23  this->SetProperty("closed", mitk::BoolProperty::New(true));
24  this->SetNumberOfPolyLines(1);
25 }
26 
27 bool mitk::PlanarRectangle::SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist)
28 {
29  // heres the deal with the rectangle:
30  // when a point is moved all corresponding corner points are moved with him
31  // e.g. if the lower right point (index=3) is moved the upper right point (index=1)
32  // is moved in the same x direction
33  // and the lower left point (index=2) is moved in the same y direction
34  // the upper left point (index=0) is left untouched
35  bool set = PlanarFigure::SetControlPoint(index, point, createIfDoesNotExist);
36 
37  if (set)
38  {
39  // can be made better ...
40  unsigned int horizontalCorrespondingPointIndex = 1;
41  unsigned int verticalCorrespondingPointIndex = 3;
42  if (index == 1)
43  {
44  horizontalCorrespondingPointIndex = 0;
45  verticalCorrespondingPointIndex = 2;
46  }
47  else if (index == 2)
48  {
49  horizontalCorrespondingPointIndex = 3;
50  verticalCorrespondingPointIndex = 1;
51  }
52  else if (index == 3)
53  {
54  horizontalCorrespondingPointIndex = 2;
55  verticalCorrespondingPointIndex = 0;
56  }
57 
58  Point2D verticalCorrespondingPoint = GetControlPoint(verticalCorrespondingPointIndex);
59  verticalCorrespondingPoint[0] = point[0];
60  PlanarFigure::SetControlPoint(verticalCorrespondingPointIndex, verticalCorrespondingPoint);
61 
62  Point2D horizontalCorrespondingPoint = GetControlPoint(horizontalCorrespondingPointIndex);
63  horizontalCorrespondingPoint[1] = point[1];
64  PlanarFigure::SetControlPoint(horizontalCorrespondingPointIndex, horizontalCorrespondingPoint);
65  }
66 
67  return set;
68 }
69 
71 {
74 }
75 
77 {
78  this->ClearPolyLines();
79 
80  for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
81  this->AppendPointToPolyLine(0, this->GetControlPoint(i));
82 }
83 
84 void mitk::PlanarRectangle::GenerateHelperPolyLine(double /*mmPerDisplayUnit*/, unsigned int /*displayHeight*/)
85 {
86  // A polygon does not require helper objects
87 }
88 
90 {
91  // Calculate circumference
92  double circumference = 0.0;
93  unsigned int i;
94  for (i = 0; i < this->GetNumberOfControlPoints(); ++i)
95  {
96  circumference += this->GetWorldControlPoint(i).EuclideanDistanceTo(
97  this->GetWorldControlPoint((i + 1) % this->GetNumberOfControlPoints()));
98  }
99 
100  this->SetQuantity(FEATURE_ID_CIRCUMFERENCE, circumference);
101 
102  // Calculate rectangle area (well, done a bit clumsy...)
103  double area = 0.0;
104  if (this->GetPlaneGeometry() != nullptr)
105  {
106  for (i = 0; i < this->GetNumberOfControlPoints(); ++i)
107  {
108  Point2D p0 = this->GetControlPoint(i);
109  Point2D p1 = this->GetControlPoint((i + 1) % this->GetNumberOfControlPoints());
110 
111  area += p0[0] * p1[1] - p1[0] * p0[1];
112  }
113  area /= 2.0;
114  }
115 
116  this->SetQuantity(FEATURE_ID_AREA, fabs(area));
117 }
118 
119 void mitk::PlanarRectangle::PrintSelf(std::ostream &os, itk::Indent indent) const
120 {
121  Superclass::PrintSelf(os, indent);
122 
123  os << indent << "Number of control points: " << this->GetNumberOfControlPoints() << std::endl;
124 
125  os << indent << "Control points:" << std::endl;
126 
127  for (unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i)
128  {
129  os << indent << indent << i << ": " << GetControlPoint(i) << std::endl;
130  }
131 }
132 
134 {
135  const auto *otherRectangle = dynamic_cast<const mitk::PlanarRectangle *>(&other);
136  if (otherRectangle)
137  {
138  return Superclass::Equals(other);
139  }
140  else
141  {
142  return false;
143  }
144 }
void GeneratePolyLine() override
Generates the poly-line representation of the planar figure.
Point2D GetControlPoint(unsigned int index) const
Returns specified control point in 2D world coordinates.
virtual const PlaneGeometry * GetPlaneGeometry() const
Returns (previously set) 2D geometry of this figure.
const unsigned int FEATURE_ID_CIRCUMFERENCE
Point3D GetWorldControlPoint(unsigned int index) const
Returns specified control point in world coordinates.
Implementation of PlanarFigure representing a polygon with two or more control points.
void ResetNumberOfControlPoints(int numberOfControlPoints)
Set the initial number of control points of the planar figure.
void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName="", bool fallBackOnDefaultContext=false) override
Add new or change existent property.
unsigned int GetNumberOfControlPoints() const
Returns the current number of 2D control points defining this figure.
static Pointer New()
void EvaluateFeaturesInternal() override
Calculates feature quantities of the planar figure.
void SetQuantity(unsigned int index, double quantity)
virtual void PlaceFigure(const Point2D &point)
Place figure at the given point (in 2D index coordinates) onto the given 2D geometry.
void AppendPointToPolyLine(unsigned int index, PolyLineElement element)
Append a point to the PolyLine # index.
void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) override
Generates the poly-lines that should be drawn the same size regardless of zoom.
void PrintSelf(std::ostream &os, itk::Indent indent) const override
void SetNumberOfPolyLines(unsigned int numberOfPolyLines)
defines the number of PolyLines that will be available
const unsigned int FEATURE_ID_AREA
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...
bool SetControlPoint(unsigned int index, const Point2D &point, bool createIfDoesNotExist=false) override
bool Equals(const mitk::PlanarFigure &other) const override
Compare two PlanarFigure objects Note: all subclasses have to implement the method on their own...
void ClearPolyLines()
clears the list of PolyLines. Call before re-calculating a new Polyline.
void PlaceFigure(const Point2D &point) override
Place figure in its minimal configuration (a point at least) onto the given 2D geometry.