00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef __VCGLIB_POINT4
00061 #define __VCGLIB_POINT4
00062 #include <assert.h>
00063
00064 #include <vcg/math/base.h>
00065
00066 namespace vcg {
00075 template <class T> class Point4
00076 {
00077 public:
00079 T _v[4];
00080
00081 public:
00082 typedef T ScalarType;
00083 enum {Dimension = 4};
00084
00086
00091 inline Point4 () { }
00092 inline Point4 ( const T nx, const T ny, const T nz , const T nw )
00093 {
00094 _v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
00095 }
00096 inline Point4 ( const T p[4] )
00097 {
00098 _v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
00099 }
00100 inline Point4 ( const Point4 & p )
00101 {
00102 _v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2]; _v[3]= p._v[3];
00103 }
00104 inline void SetZero()
00105 {
00106 _v[0] = _v[1] = _v[2] = _v[3]= 0;
00107 }
00108 template <class Q>
00110 inline void Import( const Point4<Q> & b )
00111 {
00112 _v[0] = T(b[0]); _v[1] = T(b[1]);
00113 _v[2] = T(b[2]);
00114 _v[3] = T(b[3]);
00115 }
00117 template <class Q>
00118 static inline Point4 Construct( const Point4<Q> & b )
00119 {
00120 return Point4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
00121 }
00122
00124
00126
00130 inline const T & operator [] ( const int i ) const
00131 {
00132 assert(i>=0 && i<4);
00133 return _v[i];
00134 }
00135 inline T & operator [] ( const int i )
00136 {
00137 assert(i>=0 && i<4);
00138 return _v[i];
00139 }
00140 inline T &X() {return _v[0];}
00141 inline T &Y() {return _v[1];}
00142 inline T &Z() {return _v[2];}
00143 inline T &W() {return _v[3];}
00144 inline T const * V() const
00145 {
00146 return _v;
00147 }
00148 inline T * V()
00149 {
00150 return _v;
00151 }
00152 inline const T & V ( const int i ) const
00153 {
00154 assert(i>=0 && i<4);
00155 return _v[i];
00156 }
00157 inline T & V ( const int i )
00158 {
00159 assert(i>=0 && i<4);
00160 return _v[i];
00161 }
00164 inline T Ext( const int i ) const
00165 {
00166 if(i>=0 && i<=3) return _v[i];
00167 else return 0;
00168 }
00170
00172
00174 inline Point4 operator + ( const Point4 & p) const
00175 {
00176 return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] );
00177 }
00178 inline Point4 operator - ( const Point4 & p) const
00179 {
00180 return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] );
00181 }
00182 inline Point4 operator * ( const T s ) const
00183 {
00184 return Point4( _v[0]*s, _v[1]*s, _v[2]*s, _v[3]*s );
00185 }
00186 inline Point4 operator / ( const T s ) const
00187 {
00188 return Point4( _v[0]/s, _v[1]/s, _v[2]/s, _v[3]/s );
00189 }
00190 inline Point4 & operator += ( const Point4 & p)
00191 {
00192 _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; _v[3] += p._v[3];
00193 return *this;
00194 }
00195 inline Point4 & operator -= ( const Point4 & p )
00196 {
00197 _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; _v[3] -= p._v[3];
00198 return *this;
00199 }
00200 inline Point4 & operator *= ( const T s )
00201 {
00202 _v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s;
00203 return *this;
00204 }
00205 inline Point4 & operator /= ( const T s )
00206 {
00207 _v[0] /= s; _v[1] /= s; _v[2] /= s; _v[3] /= s;
00208 return *this;
00209 }
00210 inline Point4 operator - () const
00211 {
00212 return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
00213 }
00214 inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
00215 {
00216 Point4 res;
00217 const Point4 &y = *this;
00218
00219 res[0] = y[1]*x[2]*z[3]-y[1]*x[3]*z[2]-x[1]*y[2]*z[3]+
00220 x[1]*y[3]*z[2]+z[1]*y[2]*x[3]-z[1]*y[3]*x[2];
00221 res[1] = y[0]*x[3]*z[2]-z[0]*y[2]*x[3]-y[0]*x[2]*
00222 z[3]+z[0]*y[3]*x[2]+x[0]*y[2]*z[3]-x[0]*y[3]*z[2];
00223 res[2] = -y[0]*z[1]*x[3]+x[0]*z[1]*y[3]+y[0]*x[1]*
00224 z[3]-x[0]*y[1]*z[3]-z[0]*x[1]*y[3]+z[0]*y[1]*x[3];
00225 res[3] = -z[0]*y[1]*x[2]-y[0]*x[1]*z[2]+x[0]*y[1]*
00226 z[2]+y[0]*z[1]*x[2]-x[0]*z[1]*y[2]+z[0]*x[1]*y[2];
00227 return res;
00228 }
00230
00232
00234
00235 inline T Norm() const
00236 {
00237 return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
00238 }
00240 inline T SquaredNorm() const
00241 {
00242 return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
00243 }
00245 inline Point4 & Normalize()
00246 {
00247 T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
00248 if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; _v[3] /= n; }
00249 return *this;
00250 }
00252 inline Point4 & HomoNormalize(){
00253 if (_v[3]!=0.0) { _v[0] /= _v[3]; _v[1] /= _v[3]; _v[2] /= _v[3]; _v[3]=1.0; }
00254 return *this;
00255 };
00256
00258
00260
00262 inline bool operator == ( const Point4& p ) const
00263 {
00264 return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];
00265 }
00266 inline bool operator != ( const Point4 & p ) const
00267 {
00268 return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];
00269 }
00270 inline bool operator < ( Point4 const & p ) const
00271 {
00272 return (_v[3]!=p._v[3])?(_v[3]<p._v[3]):
00273 (_v[2]!=p._v[2])?(_v[2]<p._v[2]):
00274 (_v[1]!=p._v[1])?(_v[1]<p._v[1]):
00275 (_v[0]<p._v[0]);
00276 }
00277 inline bool operator > ( const Point4 & p ) const
00278 {
00279 return (_v[3]!=p._v[3])?(_v[3]>p._v[3]):
00280 (_v[2]!=p._v[2])?(_v[2]>p._v[2]):
00281 (_v[1]!=p._v[1])?(_v[1]>p._v[1]):
00282 (_v[0]>p._v[0]);
00283 }
00284 inline bool operator <= ( const Point4 & p ) const
00285 {
00286 return (_v[3]!=p._v[3])?(_v[3]< p._v[3]):
00287 (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00288 (_v[1]!=p._v[1])?(_v[1]< p._v[1]):
00289 (_v[0]<=p._v[0]);
00290 }
00291 inline bool operator >= ( const Point4 & p ) const
00292 {
00293 return (_v[3]!=p._v[3])?(_v[3]> p._v[3]):
00294 (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00295 (_v[1]!=p._v[1])?(_v[1]> p._v[1]):
00296 (_v[0]>=p._v[0]);
00297 }
00299
00301
00304
00305 inline T operator * ( const Point4 & p ) const
00306 {
00307 return _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3];
00308 }
00309 inline T dot( const Point4 & p ) const { return (*this) * p; }
00310 inline Point4 operator ^ ( const Point4& p ) const
00311 {
00312 assert(0);
00313 return Point4();
00314 }
00315
00317 T StableDot ( const Point4<T> & p ) const
00318 {
00319
00320 T k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2], k3=_v[3]*p._v[3];
00321 int exp0,exp1,exp2,exp3;
00322
00323 frexp( double(k0), &exp0 );frexp( double(k1), &exp1 );
00324 frexp( double(k2), &exp2 );frexp( double(k3), &exp3 );
00325
00326 if (exp0>exp1) { math::Swap(k0,k1); math::Swap(exp0,exp1); }
00327 if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); }
00328 if (exp0>exp2) { math::Swap(k0,k2); math::Swap(exp0,exp2); }
00329 if (exp1>exp3) { math::Swap(k1,k3); math::Swap(exp1,exp3); }
00330 if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); }
00331
00332 return ( (k0 + k1) + k2 ) +k3;
00333 }
00335
00336
00337 };
00338
00339 template <class T>
00340 T Angle( const Point4<T>& p1, const Point4<T> & p2 )
00341 {
00342 T w = p1.Norm()*p2.Norm();
00343 if(w==0) return -1;
00344 T t = (p1*p2)/w;
00345 if(t>1) t=1;
00346 return T( math::Acos(t) );
00347 }
00348
00349 template <class T>
00350 inline T Norm( const Point4<T> & p )
00351 {
00352 return p.Norm();
00353 }
00354
00355 template <class T>
00356 inline T SquaredNorm( const Point4<T> & p )
00357 {
00358 return p.SquaredNorm();
00359 }
00360
00361 template <class T>
00362 inline T Distance( const Point4<T> & p1, const Point4<T> & p2 )
00363 {
00364 return Norm(p1-p2);
00365 }
00366
00367 template <class T>
00368 inline T SquaredDistance( const Point4<T> & p1, const Point4<T> & p2 )
00369 {
00370 return SquaredNorm(p1-p2);
00371 }
00372
00374 template<class T>
00375 double StableDot ( Point4<T> const & p0, Point4<T> const & p1 )
00376 {
00377 return p0.StableDot(p1);
00378 }
00379
00380 typedef Point4<short> Point4s;
00381 typedef Point4<int> Point4i;
00382 typedef Point4<float> Point4f;
00383 typedef Point4<double> Point4d;
00384
00386 }
00387 #endif