Ellipse2D.cpp
Go to the documentation of this file.
1 //
2 // Ellipse2D.cpp
3 //
4 
5 #define _USE_MATH_DEFINES
6 #include <cmath>
7 
8 #include "Ellipse2D.hpp"
9 #include "Circle2D.hpp"
10 #include "../tools/MathToolbox.hpp"
11 #include "../tools/errorhandler.hpp"
12 
13 namespace datatypes
14 {
15 
16 // ////////////////////////////////////////////////////////////
17 
19  : m_center(0, 0)
20  , m_radius(0, 0)
21  , m_rotation(0)
22 {
24 }
25 
26 Ellipse2D::Ellipse2D(const Point2D& center, const Point2D& radius, value_type rotation)
27  : m_center(center)
28  , m_radius(radius)
29  , m_rotation(rotation)
30 {
31  assert((m_radius.getX() >= 0.0) || isNaN(m_radius.getX()));
32  assert((m_radius.getY() >= 0.0) || isNaN(m_radius.getY()));
35 }
36 
37 Ellipse2D::Ellipse2D(value_type x_center, value_type y_center, value_type x_radius, value_type y_radius, value_type rotation)
38  : m_center(x_center, y_center)
39  , m_radius(x_radius, y_radius)
40  , m_rotation(rotation)
41 {
42  assert((m_radius.getX() >= 0.0) || isNaN(m_radius.getX()));
43  assert((m_radius.getY() >= 0.0) || isNaN(m_radius.getY()));
46 }
47 
48 
50 {
51  m_radius = p;
53 }
55 {
56  m_radius.setXY(x_length, y_width);
58 }
59 
61 {
62  m_rotation = r;
64 }
65 
66 bool Ellipse2D::containsPoint(const Point2D& point) const
67 {
68  if (fuzzyCompare(m_rotation, 0.0))
69  {
70  // Rotation is zero, hence we can directly check this in
71  // cartesian coordinates.
72  value_type pointX = point.getX() - m_center.getX();
73  value_type pointY = point.getY() - m_center.getY();
74 
75  // compare position to radius
76  return (sqr(pointX / m_radius.getX()) + sqr(pointY / m_radius.getY())) < 1;
77  }
78  else
79  {
80  // 2D coordinate transformation as proposed by Uni Ulm.
81 
82  // Move coordinate system to center of the ellipse
83  value_type deltaX = point.getX() - m_center.getX();
84  value_type deltaY = point.getY() - m_center.getY();
85 
86  // If any of the X or Y components are outside of the
87  // "manhatten" diagonal bounding box, the point cannot be
88  // inside the ellipse (and we don't even have to calculate the
89  // rotated point).
90  if (std::max(std::abs(deltaX), std::abs(deltaY)) > m_radius.getX() + m_radius.getY())
91  return false;
92 
93  // Rotate by -psi
94  value_type dCos = std::cos(m_rotation);
95  value_type dSin = std::sin(m_rotation);
96  value_type pointX = dCos * deltaX + dSin * deltaY;
97  value_type pointY = -dSin * deltaX + dCos * deltaY;
98 
99  // compare position to radius
100  return (sqr(pointX / m_radius.getX()) + sqr(pointY / m_radius.getY())) < 1;
101  }
102 }
103 
104 // ////////////////////////////////////////////////////////////
105 
106 
108 {
109  // Check our assumptions about the m_radius
110  if (m_radius.getX() < 0 || m_radius.getY() < 0)
111  {
112  m_radius.setX(std::abs(m_radius.getX()));
113  m_radius.setY(std::abs(m_radius.getY()));
114  printWarning("Radius of Ellipse2D was given as negative value - silently using the absolute value instead.");
115  // This is probably better than throwing an exception.
116  //throw std::out_of_range("Radius of Ellipse2D negative - this is an invalid Ellipse2D.");
117  }
118 
119  if (isNaN(m_radius.getX()))
120  {
121  m_radius.setX(0);
122  printWarning("Radius.getX() of Ellipse2D was given as NaN value - silently using Zero instead.");
123  }
124  if (isNaN(m_radius.getY()))
125  {
126  m_radius.setY(0);
127  printWarning("Radius.getY() of Ellipse2D was given as NaN value - silently using Zero instead.");
128  }
129  if (isNaN(m_rotation))
130  {
131  m_rotation = 0;
132  printWarning("Rotation of Ellipse2D was given as NaN value - silently using Zero instead.");
133  }
135  if (!fuzzyCompare(normd_rot, m_rotation))
136  {
137  printWarning("Rotation of Ellipse2D (" + ::toString(m_rotation, 2) +
138  ") was outside of its [-pi,pi] definition range - silently normalizing it back into that range (" +
139  ::toString(normd_rot, 2) + ").");
140  m_rotation = normd_rot;
141  }
142 }
143 
144 
145 std::string Ellipse2D::toString() const
146 {
147  std::string text;
148 
149  text = "[ Center=" + getCenter().toString() +
150  " Radius=" + getRadius().toString() +
151  " Rotation=" + ::toString(getRotation(), 2) +
152  "]";
153  return text;
154 }
155 
156 } // namespace datatypes
Point2D::value_type value_type
The type of the stored x, y coordinates, and the rotation.
Definition: Ellipse2D.hpp:34
std::string toString(UINT16 digits=2) const
Text output for debugging.
Definition: Point2D.cpp:75
const Point2D & getCenter() const
Returns the center point of this Ellipse.
Definition: Ellipse2D.hpp:88
value_type getX() const
Definition: Point2D.hpp:70
bool containsPoint(const Point2D &point) const
Returns true if the given Point2D is inside this ellipse or on its outline.
Definition: Ellipse2D.cpp:66
value_type getRotation() const
Definition: Ellipse2D.hpp:104
void setX(value_type x)
Definition: Point2D.hpp:140
value_type getY() const
Definition: Point2D.hpp:73
void setRotation(value_type r)
Definition: Ellipse2D.cpp:60
void setXY(value_type x, value_type y)
Definition: Point2D.hpp:147
bool fuzzyCompare(double a, double b)
Tests if two double values are nearly equal.
Definition: MathToolbox.hpp:28
double normalizeRadians(double radians)
Definition: MathToolbox.cpp:31
void setRadius(const Point2D &p)
Sets the radius of this Ellipse. Must be non-negative.
Definition: Ellipse2D.cpp:49
void setY(value_type y)
Definition: Point2D.hpp:143
double sqr(double val)
Definition: MathToolbox.hpp:36
const Point2D & getRadius() const
Returns the radius of this Ellipse.
Definition: Ellipse2D.hpp:97
Ellipse2D()
Constructor for an all-zero Ellipse2D.
Definition: Ellipse2D.cpp:18
bool isNaN(floatT x)
Checks if a floating point value is Not-a-Number (NaN)
Definition: MathToolbox.hpp:63
std::string toString() const
Definition: Ellipse2D.cpp:145
void printWarning(std::string message)
value_type m_rotation
Definition: Ellipse2D.hpp:38


libsick_ldmrs
Author(s): SICK AG , Martin Günther , Jochen Sprickerhof
autogenerated on Sat Jun 8 2019 17:57:33