00001
00002
00003
00004
00005
00006
00007 #ifndef POINT2D_HPP
00008 #define POINT2D_HPP
00009
00010 #include <cassert>
00011 #include <iosfwd>
00012 #include <ios>
00013 #include <utility>
00014 #include <vector>
00015 #include "../tools/MathToolbox.hpp"
00016 #include "../tools/toolbox.hpp"
00017 #include "../BasicDatatypes.hpp"
00018
00019
00020 namespace datatypes
00021 {
00022
00023
00024
00025
00026
00027 class Point2D : public BasicData
00028 {
00029 public:
00031 typedef double value_type;
00032
00034 typedef value_type floatingpoint_type;
00035
00036 private:
00037 value_type m_x;
00038 value_type m_y;
00039 public:
00041 Point2D()
00042 : m_x(0)
00043 , m_y(0)
00044 { m_datatype = Datatype_Point2D; }
00045
00047 Point2D(value_type x, value_type y)
00048 : m_x(x)
00049 , m_y(y)
00050 { m_datatype = Datatype_Point2D; }
00051
00053
00054
00056
00057
00058
00059 inline virtual const UINT32 getUsedMemory() const {return sizeof(*this);};
00060
00062
00063
00067 bool isZero() const;
00068
00070 value_type getX() const { return m_x; }
00071
00073 value_type getY() const { return m_y; }
00074
00077 value_type dist() const;
00078
00081 value_type getDist() const { return dist(); }
00082
00084 value_type length() const { return dist(); }
00085
00088 value_type angle() const;
00089
00092 value_type getAngle() const { return angle(); }
00093
00098 void toPolar(value_type& dist, value_type& angle) const;
00099
00110 std::pair<value_type, value_type> toPolar() const;
00111
00117 Point2D normalized() const;
00118
00129 Point2D rotated(value_type angle_rad) const;
00130
00132
00133
00134
00135
00137
00138
00140 void setX(value_type x) { m_x = x; }
00141
00143 void setY(value_type y) { m_y = y; }
00144
00147 void setXY(value_type x, value_type y) { m_x = x; m_y = y; }
00148
00153 void normalize();
00154
00159 void rotate(value_type angle);
00160
00163 void setPolar(value_type dist, value_type angle);
00164
00167 Point2D & operator*= ( value_type factor );
00168
00171 Point2D & operator+= ( const Point2D & point );
00172
00175 Point2D & operator-= ( const Point2D & point );
00176
00179 Point2D & operator/= ( value_type divisor );
00180
00181
00182
00183
00185
00186
00189 value_type dist( const Point2D & point ) const;
00190
00193
00194
00198 value_type distSquare ( const Point2D & point ) const;
00199
00201 value_type angle(const Point2D& point) const;
00202
00203
00204
00206
00207
00209
00213 std::istream& read (std::istream& is, UINT32 version);
00214
00216
00220 void read (const BYTE*& buf, UINT32 version);
00221
00223
00227 std::ostream& write (std::ostream& os, UINT32 version) const;
00228
00230
00234 void write (BYTE*& buf, UINT32 version) const;
00235
00237 std::string toString(UINT16 digits = 2) const;
00238
00239
00240
00243 static Point2D fromPolar(value_type dist, value_type angle);
00244
00245 friend inline bool operator==(const Point2D &, const Point2D &);
00246 friend inline bool operator!=(const Point2D &, const Point2D &);
00247 friend inline const Point2D operator+(const Point2D &, const Point2D &);
00248 friend inline const Point2D operator-(const Point2D &, const Point2D &);
00249 friend inline const Point2D operator*(value_type, const Point2D &);
00250 friend inline const Point2D operator*(const Point2D &, value_type);
00251 friend inline Point2D::value_type operator*(const Point2D &p1, const Point2D &p2);
00252 friend inline const Point2D operator-(const Point2D &);
00253 friend inline const Point2D operator/(const Point2D &, value_type);
00254 };
00255
00256
00257 std::ostream& operator<<(std::ostream& os, const Point2D& point);
00258
00259
00260
00261 inline void Point2D::setPolar(value_type r, value_type angle)
00262 {
00263 m_x = r * std::cos(angle);
00264 m_y = r * std::sin(angle);
00265 }
00266
00267 inline Point2D & Point2D::operator*= ( value_type factor )
00268 {
00269 m_x *= factor;
00270 m_y *= factor;
00271 return *this;
00272 }
00273
00274 inline Point2D & Point2D::operator+= ( const Point2D & point )
00275 {
00276 m_x += point.m_x;
00277 m_y += point.m_y;
00278 return *this;
00279 }
00280
00281 inline Point2D & Point2D::operator-= ( const Point2D & point )
00282 {
00283 m_x -= point.m_x;
00284 m_y -= point.m_y;
00285 return *this;
00286 }
00287
00288 inline Point2D & Point2D::operator/= ( value_type divisor )
00289 {
00290 assert(!fuzzyCompare(divisor, value_type(0.0)));
00291 m_x /= divisor;
00292 m_y /= divisor;
00293 return *this;
00294 }
00295
00296 inline bool Point2D::isZero() const
00297 {
00298 return (fuzzyCompare(m_x, value_type(0.0)) && fuzzyCompare(m_y, value_type(0.0)));
00299 }
00300
00301
00302
00303 inline bool operator==(const Point2D &p1, const Point2D &p2)
00304 {
00305 return (fuzzyCompare(p1.m_x, p2.m_x)
00306 || (isNaN(p1.m_x) && isNaN(p2.m_x)))
00307 && (fuzzyCompare(p1.m_y, p2.m_y)
00308 || (isNaN(p1.m_y) && isNaN(p2.m_y)));
00309 }
00310
00311 inline bool operator!=(const Point2D &p1, const Point2D &p2)
00312 {
00313 return ! operator==(p1, p2);
00314 }
00315
00316 inline const Point2D operator+(const Point2D &p1, const Point2D &p2)
00317 {
00318 return Point2D(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
00319 }
00320
00321 inline const Point2D operator-(const Point2D &p1, const Point2D &p2)
00322 {
00323 return Point2D(p1.m_x - p2.m_x, p1.m_y - p2.m_y);
00324 }
00325
00326 inline const Point2D operator*(const Point2D &p, Point2D::value_type factor)
00327 {
00328 return Point2D(p.m_x * factor, p.m_y * factor);
00329 }
00330
00331 inline const Point2D operator*(Point2D::value_type factor, const Point2D &p)
00332 {
00333 return Point2D(p.m_x * factor, p.m_y * factor);
00334 }
00335
00336 inline Point2D::value_type operator*(const Point2D &p1, const Point2D &p2)
00337 {
00338 return p1.m_x * p2.m_x + p1.m_y * p2.m_y;
00339 }
00340
00341 inline const Point2D operator-(const Point2D &p)
00342 {
00343 return Point2D(-p.m_x, -p.m_y);
00344 }
00345
00346 inline const Point2D operator/(const Point2D &p, Point2D::value_type divisor)
00347 {
00348 assert(!fuzzyCompare(divisor, Point2D::value_type(0.0)));
00349 return Point2D(p.m_x / divisor, p.m_y / divisor);
00350 }
00351
00352
00353 inline Point2D::value_type Point2D::dist() const
00354 {
00355 return hypot(m_x, m_y);
00356 }
00357
00358 inline Point2D::value_type Point2D::angle() const
00359 {
00360 return atan2(m_y, m_x);
00361 }
00362
00363 inline Point2D::value_type Point2D::angle(const Point2D& point) const
00364 {
00365 const double divisor(dist() * point.dist());
00366 assert(!fuzzyCompare(divisor, 0.0));
00367
00368 return acos( (*this * point) / divisor );
00369 }
00370
00371 inline void Point2D::toPolar(Point2D::value_type& r, Point2D::value_type& psi) const
00372 {
00373 r = dist();
00374 psi = angle();
00375 }
00376
00377 inline std::pair<Point2D::value_type, Point2D::value_type> Point2D::toPolar() const
00378 {
00379 return std::make_pair(dist(), angle());
00380 }
00381
00382 }
00383
00384 #endif