Ellipse2D.cpp
Go to the documentation of this file.
00001 //
00002 // Ellipse2D.cpp
00003 //
00004 
00005 #define _USE_MATH_DEFINES
00006 #include <cmath>
00007 
00008 #include "Ellipse2D.hpp"
00009 #include "Circle2D.hpp"
00010 #include "../tools/MathToolbox.hpp"
00011 #include "../tools/errorhandler.hpp"
00012 
00013 namespace datatypes
00014 {
00015 
00016 // ////////////////////////////////////////////////////////////
00017 
00018 Ellipse2D::Ellipse2D()
00019         : m_center(0, 0)
00020         , m_radius(0, 0)
00021         , m_rotation(0)
00022 {
00023         m_datatype = Datatype_Circle2D;
00024 }
00025 
00026 Ellipse2D::Ellipse2D(const Point2D& center, const Point2D& radius, value_type rotation)
00027         : m_center(center)
00028         , m_radius(radius)
00029         , m_rotation(rotation)
00030 {
00031         assert((m_radius.getX() >= 0.0) || isNaN(m_radius.getX()));
00032         assert((m_radius.getY() >= 0.0) || isNaN(m_radius.getY()));
00033         verifyNumericRanges();
00034         m_datatype = Datatype_Circle2D;
00035 }
00036 
00037 Ellipse2D::Ellipse2D(value_type x_center, value_type y_center, value_type x_radius, value_type y_radius, value_type rotation)
00038         : m_center(x_center, y_center)
00039         , m_radius(x_radius, y_radius)
00040         , m_rotation(rotation)
00041 {
00042         assert((m_radius.getX() >= 0.0) || isNaN(m_radius.getX()));
00043         assert((m_radius.getY() >= 0.0) || isNaN(m_radius.getY()));
00044         verifyNumericRanges();
00045         m_datatype = Datatype_Circle2D;
00046 }
00047 
00048 
00049 void Ellipse2D::setRadius(const Point2D& p)
00050 {
00051         m_radius = p;
00052         verifyNumericRanges();
00053 }
00054 void Ellipse2D::setRadius(value_type x_length, value_type y_width)
00055 {
00056         m_radius.setXY(x_length, y_width);
00057         verifyNumericRanges();
00058 }
00059 
00060 void Ellipse2D::setRotation(value_type r)
00061 {
00062         m_rotation = r;
00063         verifyNumericRanges();
00064 }
00065 
00066 bool Ellipse2D::containsPoint(const Point2D& point) const
00067 {
00068         if (fuzzyCompare(m_rotation, 0.0))
00069         {
00070                 // Rotation is zero, hence we can directly check this in
00071                 // cartesian coordinates.
00072                 value_type pointX = point.getX() - m_center.getX();
00073                 value_type pointY = point.getY() - m_center.getY();
00074 
00075                 // compare position to radius
00076                 return (sqr(pointX / m_radius.getX()) + sqr(pointY / m_radius.getY())) < 1;
00077         }
00078         else
00079         {
00080                 // 2D coordinate transformation as proposed by Uni Ulm.
00081 
00082                 // Move coordinate system to center of the ellipse
00083                 value_type deltaX = point.getX() - m_center.getX();
00084                 value_type deltaY = point.getY() - m_center.getY();
00085 
00086                 // If any of the X or Y components are outside of the
00087                 // "manhatten" diagonal bounding box, the point cannot be
00088                 // inside the ellipse (and we don't even have to calculate the
00089                 // rotated point).
00090                 if (std::max(std::abs(deltaX), std::abs(deltaY)) > m_radius.getX() + m_radius.getY())
00091                         return false;
00092 
00093                 // Rotate by -psi
00094                 value_type dCos = std::cos(m_rotation);
00095                 value_type dSin = std::sin(m_rotation);
00096                 value_type pointX =  dCos * deltaX  +  dSin * deltaY;
00097                 value_type pointY = -dSin * deltaX  +  dCos * deltaY;
00098 
00099                 // compare position to radius
00100                 return (sqr(pointX / m_radius.getX()) + sqr(pointY / m_radius.getY())) < 1;
00101         }
00102 }
00103 
00104 // ////////////////////////////////////////////////////////////
00105 
00106 
00107 void Ellipse2D::verifyNumericRanges()
00108 {
00109         // Check our assumptions about the m_radius
00110         if (m_radius.getX() < 0 || m_radius.getY() < 0)
00111         {
00112                 m_radius.setX(std::abs(m_radius.getX()));
00113                 m_radius.setY(std::abs(m_radius.getY()));
00114                 printWarning("Radius of Ellipse2D was given as negative value - silently using the absolute value instead.");
00115                 // This is probably better than throwing an exception.
00116                 //throw std::out_of_range("Radius of Ellipse2D negative - this is an invalid Ellipse2D.");
00117         }
00118 
00119         if (isNaN(m_radius.getX()))
00120         {
00121                 m_radius.setX(0);
00122                 printWarning("Radius.getX() of Ellipse2D was given as NaN value - silently using Zero instead.");
00123         }
00124         if (isNaN(m_radius.getY()))
00125         {
00126                 m_radius.setY(0);
00127                 printWarning("Radius.getY() of Ellipse2D was given as NaN value - silently using Zero instead.");
00128         }
00129         if (isNaN(m_rotation))
00130         {
00131                 m_rotation = 0;
00132                 printWarning("Rotation of Ellipse2D was given as NaN value - silently using Zero instead.");
00133         }
00134         value_type normd_rot = normalizeRadians(m_rotation);
00135         if (!fuzzyCompare(normd_rot, m_rotation))
00136         {
00137                 printWarning("Rotation of Ellipse2D (" + ::toString(m_rotation, 2) +
00138                                         ") was outside of its [-pi,pi] definition range - silently normalizing it back into that range (" +
00139                                         ::toString(normd_rot, 2) + ").");
00140                 m_rotation = normd_rot;
00141         }
00142 }
00143 
00144 
00145 std::string Ellipse2D::toString() const
00146 {
00147         std::string text;
00148         
00149         text = "[ Center=" + getCenter().toString() +
00150                         " Radius=" + getRadius().toString() +
00151                         " Rotation=" + ::toString(getRotation(), 2) +
00152                         "]";
00153         return text;
00154 }
00155 
00156 }       // namespace datatypes


libsick_ldmrs
Author(s): SICK AG , Martin Günther , Jochen Sprickerhof
autogenerated on Thu Jun 6 2019 21:02:36