00001 #ifndef POINT2D_H_
00002 #define POINT2D_H_
00003
00004 #include "Point3D.h"
00005
00006 #include <cmath>
00007
00008 #include <ostream>
00009 using std::ostream;
00010 using std::cout;
00011
00012 #include <boost/tuple/tuple.hpp>
00013 #include <boost/functional/hash.hpp>
00014 using boost::hash;
00015 using boost::hash_combine;
00016
00017 template<class T>
00018 class Point2D
00019 {
00020 public:
00021 friend class Point3D<T>;
00022
00023 Point2D(T x, T y)
00024 : _x(x), _y(y)
00025 {}
00026
00027 Point2D(const Point2D<T> &other)
00028 : _x(other.x()), _y(other.y())
00029 {
00030 }
00031
00032 Point2D(const Point3D<T> &other)
00033 : _x(other.x()), _y(other.y())
00034 {
00035 }
00036
00037 Point2D()
00038 : _x(T()), _y(T())
00039 {}
00040
00041
00042 virtual ~Point2D()
00043 {}
00044
00045
00046 T x() const
00047 {
00048 return _x;
00049 }
00050
00051 T y() const
00052 {
00053 return _y;
00054 }
00055
00056 void x(const T &xc)
00057 {
00058 _x = xc;
00059 }
00060
00061 void y(const T &yc)
00062 {
00063 _y = yc;
00064 }
00065
00066 void set(T x, T y)
00067 {
00068 _x = x;
00069 _y = y;
00070 }
00071
00072 T sqr_distance(const Point2D<T> &other) const
00073 {
00074 return operator-(other).sqr_abs();
00075 }
00076
00077 double distance(const Point2D<T> &other) const
00078 {
00079 return operator-(other).abs();
00080 }
00081
00082 void rotate(double theta)
00083 {
00084 double new_x = cos(theta)*_x + sin(theta)*_y;
00085 _y = -sin(theta)*_x + cos(theta)*_y;
00086
00087 _x = new_x;
00088 }
00089
00090
00091 T sqr_abs() const
00092 {
00093 return _x*_x + _y*_y;
00094 }
00095
00096 double abs() const
00097 {
00098 return sqrt((double)sqr_abs());
00099 }
00100
00101 Point2D<T> operator+(const Point2D<T> &other) const
00102 {
00103 return Point2D<T>(_x + other._x,
00104 _y + other._y);
00105 }
00106
00107 Point2D<T> operator-(const Point2D<T> &other) const
00108 {
00109 return Point2D<T>(_x - other._x,
00110 _y - other._y);
00111 }
00112
00113 Point2D<T> operator*(const T scale) const
00114 {
00115 return Point2D<T>(_x * scale,
00116 _y * scale);
00117 }
00118
00119 Point2D<T> operator/(const T scale) const
00120 {
00121 return Point2D<T>(_x / scale,
00122 _y / scale);
00123 }
00124
00125 Point2D<T> &operator+=(const Point2D<T> &other)
00126 {
00127 _x += other._x;
00128 _y += other._y;
00129 return *this;
00130 }
00131
00132 Point2D<T> &operator-=(const Point2D<T> &other)
00133 {
00134 _x -= other._x;
00135 _y -= other._y;
00136 return *this;
00137 }
00138
00139 Point2D<T> &operator*=(const T scale)
00140 {
00141 _x *= scale;
00142 _y *= scale;
00143 return *this;
00144 }
00145
00146 Point2D<T> &operator/=(const T scale)
00147 {
00148 _x /= scale;
00149 _y /= scale;
00150 return *this;
00151 }
00152
00153 bool operator==(const Point2D<T> &other) const
00154 {
00155 return (_x == other._x && _y == other._y);
00156 };
00157
00158 friend std::size_t hash_value(Point2D<T> const& p)
00159 {
00160 std::size_t seed = 0;
00161 boost::hash_combine(seed, p._x);
00162 boost::hash_combine(seed, p._y);
00163 return seed;
00164 }
00165
00166 template<class U>
00167 friend ostream & operator<<( ostream & ss, const Point2D<U> & p);
00168
00169 protected:
00170 T _x;
00171 T _y;
00172 };
00173
00174 template< typename T>
00175 Point2D<T> operator-(const Point2D<T> & p)
00176 {
00177 return Point2D<T>() - p;
00178 }
00179
00180
00181 template< typename T>
00182 T sqr_distance(const Point2D<T> &p1, const Point2D<T> &p2)
00183 {
00184 return (p1 - p2).sqr_abs();
00185 }
00186
00187 template< typename T>
00188 double distance(Point2D<T> &p1, Point2D<T> &p2)
00189 {
00190 return (p1 - p2).abs();
00191 }
00192
00193 template< typename T>
00194 ostream & operator <<( ostream & ss, const Point2D<T> & p)
00195 {
00196 return ss << "[" << p._x << ", " << p._y << "]";
00197 }
00198
00199 template< typename T>
00200 size_t hash_value( Point2D<double> const& p )
00201 {
00202 size_t seed = 0;
00203 hash_combine( seed, p.x());
00204 hash_combine( seed, p.y());
00205 return seed;
00206 }
00207
00208 typedef Point2D<double> Point2Dd;
00209
00210 typedef Point2D<float> Point2Df;
00211
00212 typedef Point2D<int> GridPoint2D;
00213
00214
00215 class Volume2DSize
00216 {
00217 public:
00218
00219 typedef enum { X = 0, Y = 1} Coordinate;
00220
00221 explicit Volume2DSize(size_t x = 1, size_t y = 1)
00222 : _x(x), _y(y)
00223 {
00224 }
00225
00226 size_t operator[] ( int idx) const
00227 {
00228 switch(idx) {
00229 case X:
00230 return _x;
00231 case Y:
00232 return _y;
00233 }
00234 return 0;
00235 }
00236
00237 size_t x() const
00238 {
00239 return _x;
00240 }
00241
00242 size_t y() const
00243 {
00244 return _y;
00245 }
00246
00247 size_t numPoints() const
00248 {
00249 return _x * _y;
00250 }
00251
00252 protected:
00253 size_t _x;
00254 size_t _y;
00255 };
00256
00257
00258
00259 #if !defined(max)
00260 #define max(A, B) ((A) > (B) ? (A) : (B))
00261 #endif
00262 #if !defined(min)
00263 #define min(A, B) ((A) < (B) ? (A) : (B))
00264 #endif
00265
00266
00267 template<class T>
00268 class Point2DDistance
00269 {
00270 public:
00271 Point2DDistance(bool toroid=true, T toroid_off=0,
00272 int src_shape_x=1, int src_shape_y=1,
00273 int dst_shape_x=1, int dst_shape_y=1,
00274 double src_scale=1.0, double dst_scale=1.0,
00275 Point2D<T> src_center=Point2D<T>(),
00276 Point2D<T> dst_center=Point2D<T>())
00277 : _toroid(toroid)
00278 , _toroid_off(toroid_off)
00279 , _src_scale(src_scale)
00280 , _dst_scale(dst_scale)
00281 , _src_center(src_center)
00282 , _dst_center(dst_center)
00283 , _src_shape_x(src_shape_x)
00284 , _src_shape_y(src_shape_y)
00285 , _dst_shape_x(dst_shape_x)
00286 , _dst_shape_y(dst_shape_y)
00287 {
00288
00289 _min_sx = (T)(_src_scale * (-(T)(_src_shape_x - 1) / 2 ) - _toroid_off);
00290 _max_sx = (T)(_src_scale * ((T)(_src_shape_x - 1) / 2 ));
00291 _min_dx = (T)(_dst_scale * (-(T)(_dst_shape_x - 1) / 2) - _toroid_off);
00292 _max_dx = (T)(_dst_scale * ((T)(_dst_shape_x - 1) / 2));
00293
00294
00295 _min_sy = (T)(_src_scale * (-(T)(_src_shape_y - 1) / 2) - _toroid_off);
00296 _max_sy = (T)(_src_scale * ((T)(_src_shape_y - 1) / 2));
00297 _min_dy = (T)(_dst_scale * (-(T)(_dst_shape_y - 1) / 2) - _toroid_off);
00298 _max_dy = (T)(_dst_scale * ((T)(_dst_shape_y - 1) / 2));
00299 }
00300
00301
00302 T sqr_distance(const Point2D<T> &src, const Point2D<T> &dst) const
00303 {
00304 Point2D<T> s = (src - _src_center)*_src_scale;
00305 Point2D<T> d = (dst - _dst_center)*_dst_scale;
00306
00307 if (_toroid == false)
00308 {
00309 return s.sqr_distance(d);
00310 }
00311 else
00312 {
00313 T d1 = fabs(d.x() - s.x());
00314 T d2 = fabs(_max_dx - d.x()) + fabs(_min_sx - s.x());
00315 T d3 = fabs(_max_sx - s.x()) + fabs(_min_dx - d.x());
00316
00317 T dx = min(min(d1, d2), d3);
00318
00319 d1 = fabs(d.y() - s.y());
00320 d2 = fabs(_max_dy - d.y()) + fabs(_min_sy - s.y());
00321 d3 = fabs(_max_sy - s.y()) + fabs(_min_dy - d.y());
00322
00323 T dy = min(min(d1, d2), d3);
00324
00325 return dx*dx + dy*dy;
00326 }
00327 }
00328
00329
00330 Point2D<T> diff(const Point2D<T> &src, const Point2D<T> &dst) const
00331 {
00332 Point2D<T> s = (src - _src_center)*_src_scale;
00333 Point2D<T> d = (dst - _dst_center)*_dst_scale;
00334
00335 if(_toroid == false)
00336 {
00337 return Point2D<T>(s-d);
00338 }
00339 else
00340 {
00341 T d1 = fabs(d.x() - s.x());
00342 T d2 = fabs(_max_dx - d.x()) + fabs(_min_sx - s.x());
00343 T d3 = fabs(_max_sx - s.x()) + fabs(_min_dx - d.x());
00344
00345 T dx = min(min(d1, d2), d3);
00346
00347 d1 = fabs(d.y() - s.y());
00348 d2 = fabs(_max_dy - d.y()) + fabs(_min_sy - s.y());
00349 d3 = fabs(_max_sy - s.y()) + fabs(_min_dy - d.y());
00350
00351 T dy = min(min(d1, d2), d3);
00352
00353 return Point2D<T>(dx, dy);
00354 }
00355 }
00356
00357 T distance(Point2D<T> &src, Point2D<T> &dst) const
00358 {
00359 return sqrt(sqr_distance(src, dst));
00360 }
00361
00362
00363 public:
00364 bool _toroid;
00365 T _toroid_off;
00366
00367 double _src_scale;
00368 double _dst_scale;
00369
00370 Point2D<T> _src_center;
00371 Point2D<T> _dst_center;
00372
00373 int _src_shape_x;
00374 int _src_shape_y;
00375 int _dst_shape_x;
00376 int _dst_shape_y;
00377
00378 T _min_dx, _min_dy, _max_dx, _max_dy;
00379 T _min_sx, _min_sy, _max_sx, _max_sy;
00380 };
00381
00382
00383 namespace instantiate2d {
00384 inline int instantiate() {
00385 int m = sizeof( Point2D<int> );
00386 int n = m + sizeof( GridPoint2D );
00387 Point2D<int> a;
00388 GridPoint2D b;
00389 distance( a, b);
00390 sqr_distance(a, b);
00391 GridPoint2D c = -b;
00392 Point2D<double> d(1,2);
00393 Point2Dd dd(1.,2.);
00394 Point2D<float> f(1,2);
00395 Point2DDistance<double> pdistd;
00396 Point2DDistance<float> pdistf;
00397 Point2DDistance<int> pdisti;
00398 return n;
00399 }
00400 }
00401
00402 #endif