Point2D.h

Go to the documentation of this file.
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         //x in centered coordinates
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         //y
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 //protected:
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 /*Point2D_H_*/

Generated on Wed Jul 9 16:34:39 2008 for PCSIM by  doxygen 1.5.5