00001 #ifndef POINT3D_H_
00002 #define POINT3D_H_
00003
00004 #include <cmath>
00005
00006 #include <ostream>
00007 using std::ostream;
00008
00009 #include <boost/tuple/tuple.hpp>
00010 #include <boost/functional/hash.hpp>
00011 using boost::hash;
00012 using boost::hash_combine;
00013
00014 template<class T>
00015 class Point3D
00016 {
00017 public:
00018 Point3D(T x, T y, T z) :
00019 _x(x), _y(y), _z(z)
00020 {}
00021 ;
00022
00023 Point3D()
00024 : _x(T()), _y(T()), _z(T())
00025 {}
00026 ;
00027
00028 virtual ~Point3D()
00029 {}
00030 ;
00031
00032 T x() const
00033 {
00034 return _x;
00035 }
00036
00037 T y() const
00038 {
00039 return _y;
00040 }
00041
00042 T z() const
00043
00044 {
00045 return _z;
00046 }
00047
00048 void x(const T &xc)
00049 {
00050 _x = xc;
00051 }
00052
00053 void y(const T &yc)
00054 {
00055 _y = yc;
00056 }
00057
00058 void z(const T &zc)
00059 {
00060 _z = zc;
00061 }
00062
00063
00064 void set(T x, T y, T z)
00065 {
00066 _x = x;
00067 _y = y;
00068 _z = z;
00069 }
00070
00071 T sqr_distance(const Point3D<T> &other) const
00072 {
00073 return operator-(other).sqr_abs();
00074 }
00075
00076 double distance(const Point3D<T> &other) const
00077 {
00078 return operator-(other).abs();
00079 }
00080
00081
00082 T sqr_abs() const
00083 {
00084 return _x*_x + _y*_y + _z*_z;
00085 }
00086
00087 double abs() const
00088 {
00089 return sqrt((double)sqr_abs());
00090 }
00091
00092 Point3D<T> operator+(const Point3D<T> &other) const
00093 {
00094 return Point3D<T>(_x + other._x,
00095 _y + other._y,
00096 _z + other._z);
00097 }
00098
00099 Point3D<T> operator-(const Point3D<T> &other) const
00100 {
00101 return Point3D<T>(_x - other._x,
00102 _y - other._y,
00103 _z - other._z);
00104 }
00105
00106 Point3D<T> &operator+=(const Point3D<T> &other)
00107 {
00108 _x += other._x;
00109 _y += other._y;
00110 _z += other._z;
00111 return *this;
00112 }
00113
00114 Point3D<T> &operator-=(const Point3D<T> &other)
00115 {
00116 _x -= other._x;
00117 _y -= other._y;
00118 _z -= other._z;
00119 return *this;
00120 }
00121
00122 bool operator==(const Point3D<T> &other) const
00123 {
00124 return (_x == other._x && _y == other._y && _z == other._z);
00125 };
00126
00127 friend std::size_t hash_value(Point3D<T> const& p)
00128 {
00129 std::size_t seed = 0;
00130 boost::hash_combine(seed, p._x);
00131 boost::hash_combine(seed, p._y);
00132 boost::hash_combine(seed, p._z);
00133 return seed;
00134 }
00135
00136 template<class U>
00137 friend ostream & operator<<( ostream & ss, const Point3D<U> & p);
00138
00139 protected:
00140 T _x;
00141 T _y;
00142 T _z;
00143 };
00144
00145 template< typename T>
00146 Point3D<T> operator-(const Point3D<T> & p)
00147 {
00148 return Point3D<T>() - p;
00149 }
00150
00151
00152 template< typename T>
00153 T sqr_distance(const Point3D<T> &p1, const Point3D<T> &p2)
00154 {
00155 return (p1 - p2).sqr_abs();
00156 }
00157
00158 template< typename T>
00159 double distance(Point3D<T> &p1, Point3D<T> &p2)
00160 {
00161 return (p1 - p2).abs();
00162 }
00163
00164 template< typename T>
00165 ostream & operator <<( ostream & ss, const Point3D<T> & p)
00166 {
00167 return ss << "[" << p._x << ", " << p._y << ", " << p._z << "]";
00168 }
00169
00170 template< typename T>
00171 size_t hash_value( Point3D<double> const& p )
00172 {
00173 size_t seed = 0;
00174 hash_combine( seed, p.x());
00175 hash_combine( seed, p.y());
00176 hash_combine( seed, p.z());
00177 return seed;
00178 }
00179
00180 typedef Point3D<double> Point3Dd;
00181
00182 typedef Point3D<float> Point3Df;
00183
00184 typedef Point3D<int> GridPoint3D;
00185
00186 namespace instantiate {
00187 inline int instantiate() {
00188 int m = sizeof( Point3D<int> );
00189 int n = m + sizeof( GridPoint3D );
00190 Point3D<int> a;
00191 GridPoint3D b;
00192 distance( a, b);
00193 sqr_distance(a, b);
00194 GridPoint3D c = -b;
00195 Point3D<double> d(1,2,3);
00196 Point3Dd dd(1,2,3);
00197 Point3D<float> f(1,2,3);
00198 return n;
00199 }
00200 }
00201
00202
00203 class Volume3DSize
00204 {
00205 public:
00206
00207 typedef enum { X = 0, Y = 1, Z = 2 } Coordinate;
00208
00209 explicit Volume3DSize(size_t x = 1, size_t y = 1, size_t z = 1)
00210 : _x(x), _y(y), _z(z)
00211 {
00212 }
00213
00214 size_t operator[] ( int idx) const
00215 {
00216 switch(idx) {
00217 case X:
00218 return _x;
00219 case Y:
00220 return _y;
00221 case Z:
00222 return _z;
00223 }
00224 return 0;
00225 }
00226
00227 size_t x() const
00228 {
00229 return _x;
00230 }
00231
00232 size_t y() const
00233 {
00234 return _y;
00235 }
00236
00237
00238 size_t z() const
00239 {
00240 return _z;
00241 }
00242
00243 size_t numPoints() const
00244 {
00245 return _x * _y * _z;
00246 }
00247
00248 protected:
00249 size_t _x;
00250 size_t _y;
00251 size_t _z;
00252 };
00253
00254
00255 #endif