Go to the documentation of this file.00001
00002
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
00071
00072 value_type pointX = point.getX() - m_center.getX();
00073 value_type pointY = point.getY() - m_center.getY();
00074
00075
00076 return (sqr(pointX / m_radius.getX()) + sqr(pointY / m_radius.getY())) < 1;
00077 }
00078 else
00079 {
00080
00081
00082
00083 value_type deltaX = point.getX() - m_center.getX();
00084 value_type deltaY = point.getY() - m_center.getY();
00085
00086
00087
00088
00089
00090 if (std::max(std::abs(deltaX), std::abs(deltaY)) > m_radius.getX() + m_radius.getY())
00091 return false;
00092
00093
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
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
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
00116
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 }