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
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 #ifndef __VCGLIB_POINT3
00095 #define __VCGLIB_POINT3
00096
00097 #include <assert.h>
00098 #include <algorithm>
00099 #include <vcg/math/base.h>
00100
00101 namespace vcg {
00102
00110 template <class T> class Box3;
00111
00112 template <class P3ScalarType> class Point3
00113 {
00114 protected:
00116 P3ScalarType _v[3];
00117
00118 public:
00119 typedef P3ScalarType ScalarType;
00120 enum {Dimension = 3};
00121
00122
00124
00129 inline Point3 () { }
00130 inline Point3 ( const P3ScalarType nx, const P3ScalarType ny, const P3ScalarType nz )
00131 {
00132 _v[0] = nx;
00133 _v[1] = ny;
00134 _v[2] = nz;
00135 }
00136 inline Point3 ( Point3 const & p )
00137 {
00138 _v[0]= p._v[0];
00139 _v[1]= p._v[1];
00140 _v[2]= p._v[2];
00141 }
00142 inline Point3 ( const P3ScalarType nv[3] )
00143 {
00144 _v[0] = nv[0];
00145 _v[1] = nv[1];
00146 _v[2] = nv[2];
00147 }
00148 inline Point3 & operator =( Point3 const & p )
00149 {
00150 _v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2];
00151 return *this;
00152 }
00153 inline void SetZero()
00154 {
00155 _v[0] = 0;
00156 _v[1] = 0;
00157 _v[2] = 0;
00158 }
00159
00162 inline P3ScalarType Ext( const int i ) const
00163 {
00164 if(i>=0 && i<=2) return _v[i];
00165 else return 0;
00166 }
00167
00168 template <class Q>
00169 inline void Import( const Point3<Q> & b )
00170 {
00171 _v[0] = P3ScalarType(b[0]);
00172 _v[1] = P3ScalarType(b[1]);
00173 _v[2] = P3ScalarType(b[2]);
00174 }
00175 template <class EigenVector>
00176 inline void FromEigenVector( const EigenVector & b )
00177 {
00178 _v[0] = P3ScalarType(b[0]);
00179 _v[1] = P3ScalarType(b[1]);
00180 _v[2] = P3ScalarType(b[2]);
00181 }
00182 template <class EigenVector>
00183 inline void ToEigenVector( EigenVector & b ) const
00184 {
00185 b[0]=_v[0] ;
00186 b[1]=_v[1] ;
00187 b[2]=_v[2] ;
00188 }
00189 template <class Q>
00190 static inline Point3 Construct( const Point3<Q> & b )
00191 {
00192 return Point3(P3ScalarType(b[0]),P3ScalarType(b[1]),P3ScalarType(b[2]));
00193 }
00194
00195 template <class Q>
00196 static inline Point3 Construct( const Q & P0, const Q & P1, const Q & P2)
00197 {
00198 return Point3(P3ScalarType(P0),P3ScalarType(P1),P3ScalarType(P2));
00199 }
00200
00201 static inline Point3 Construct( const Point3<ScalarType> & b )
00202 {
00203 return b;
00204 }
00205
00206 static inline Point3 Zero(void)
00207 {
00208 return Point3(0,0,0);
00209 }
00210
00212
00214
00218 inline P3ScalarType & operator [] ( const int i )
00219 {
00220 assert(i>=0 && i<3);
00221 return _v[i];
00222 }
00223 inline const P3ScalarType & operator [] ( const int i ) const
00224 {
00225 assert(i>=0 && i<3);
00226 return _v[i];
00227 }
00228 inline const P3ScalarType &X() const { return _v[0]; }
00229 inline const P3ScalarType &Y() const { return _v[1]; }
00230 inline const P3ScalarType &Z() const { return _v[2]; }
00231 inline P3ScalarType &X() { return _v[0]; }
00232 inline P3ScalarType &Y() { return _v[1]; }
00233 inline P3ScalarType &Z() { return _v[2]; }
00234 inline const P3ScalarType * V() const
00235 {
00236 return _v;
00237 }
00238 inline P3ScalarType * V()
00239 {
00240 return _v;
00241 }
00242 inline P3ScalarType & V( const int i )
00243 {
00244 assert(i>=0 && i<3);
00245 return _v[i];
00246 }
00247 inline const P3ScalarType & V( const int i ) const
00248 {
00249 assert(i>=0 && i<3);
00250 return _v[i];
00251 }
00253
00254
00259 inline Point3 operator + ( Point3 const & p) const
00260 {
00261 return Point3<P3ScalarType>( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2] );
00262 }
00263 inline Point3 operator - ( Point3 const & p) const
00264 {
00265 return Point3<P3ScalarType>( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2] );
00266 }
00267 inline Point3 operator * ( const P3ScalarType s ) const
00268 {
00269 return Point3<P3ScalarType>( _v[0]*s, _v[1]*s, _v[2]*s );
00270 }
00271 inline Point3 operator / ( const P3ScalarType s ) const
00272 {
00273 return Point3<P3ScalarType>( _v[0]/s, _v[1]/s, _v[2]/s );
00274 }
00276 inline P3ScalarType operator * ( Point3 const & p ) const
00277 {
00278 return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] );
00279 }
00280 inline P3ScalarType dot( const Point3 & p ) const { return (*this) * p; }
00282 inline Point3 operator ^ ( Point3 const & p ) const
00283 {
00284 return Point3 <P3ScalarType>
00285 (
00286 _v[1]*p._v[2] - _v[2]*p._v[1],
00287 _v[2]*p._v[0] - _v[0]*p._v[2],
00288 _v[0]*p._v[1] - _v[1]*p._v[0]
00289 );
00290 }
00291
00292 inline Point3 & operator += ( Point3 const & p)
00293 {
00294 _v[0] += p._v[0];
00295 _v[1] += p._v[1];
00296 _v[2] += p._v[2];
00297 return *this;
00298 }
00299 inline Point3 & operator -= ( Point3 const & p)
00300 {
00301 _v[0] -= p._v[0];
00302 _v[1] -= p._v[1];
00303 _v[2] -= p._v[2];
00304 return *this;
00305 }
00306 inline Point3 & operator *= ( const P3ScalarType s )
00307 {
00308 _v[0] *= s;
00309 _v[1] *= s;
00310 _v[2] *= s;
00311 return *this;
00312 }
00313 inline Point3 & operator /= ( const P3ScalarType s )
00314 {
00315 _v[0] /= s;
00316 _v[1] /= s;
00317 _v[2] /= s;
00318 return *this;
00319 }
00320
00321 inline P3ScalarType Norm() const
00322 {
00323 return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
00324 }
00325 inline P3ScalarType SquaredNorm() const
00326 {
00327 return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
00328 }
00329
00330 inline Point3 & Scale( const P3ScalarType sx, const P3ScalarType sy, const P3ScalarType sz )
00331 {
00332 _v[0] *= sx;
00333 _v[1] *= sy;
00334 _v[2] *= sz;
00335 return *this;
00336 }
00337 inline Point3 & Scale( const Point3 & p )
00338 {
00339 _v[0] *= p._v[0];
00340 _v[1] *= p._v[1];
00341 _v[2] *= p._v[2];
00342 return *this;
00343 }
00344
00345
00346 inline Point3 & Normalize()
00347 {
00348 P3ScalarType n = P3ScalarType(math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2]));
00349 if (n > P3ScalarType(0)) { _v[0] /= n; _v[1] /= n; _v[2] /= n; }
00350 return *this;
00351 }
00352
00353
00354 inline Point3 & normalized() { return Normalize(); }
00355
00366 void ToPolarRad(P3ScalarType &ro, P3ScalarType &theta, P3ScalarType &phi) const
00367 {
00368 ro = Norm();
00369 theta = (P3ScalarType)atan2(_v[2], _v[0]);
00370 phi = (P3ScalarType)asin(_v[1]/ro);
00371 }
00372
00383 void FromPolarRad(const P3ScalarType &ro, const P3ScalarType &theta, const P3ScalarType &phi)
00384 {
00385 _v[0]= ro*cos(theta)*cos(phi);
00386 _v[1]= ro*sin(phi);
00387 _v[2]= ro*sin(theta)*cos(phi);
00388 }
00389
00390 Box3<P3ScalarType> GetBBox(Box3<P3ScalarType> &bb) const;
00392
00393
00394 size_t MaxCoeffId() const
00395 {
00396 if (_v[0]>_v[1])
00397 return _v[0]>_v[2] ? 0 : 2;
00398 else
00399 return _v[1]>_v[2] ? 1 : 2;
00400 }
00405 inline bool operator == ( Point3 const & p ) const
00406 {
00407 return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2];
00408 }
00409 inline bool operator != ( Point3 const & p ) const
00410 {
00411 return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2];
00412 }
00413 inline bool operator < ( Point3 const & p ) const
00414 {
00415 return (_v[2]!=p._v[2])?(_v[2]<p._v[2]):
00416 (_v[1]!=p._v[1])?(_v[1]<p._v[1]):
00417 (_v[0]<p._v[0]);
00418 }
00419 inline bool operator > ( Point3 const & p ) const
00420 {
00421 return (_v[2]!=p._v[2])?(_v[2]>p._v[2]):
00422 (_v[1]!=p._v[1])?(_v[1]>p._v[1]):
00423 (_v[0]>p._v[0]);
00424 }
00425 inline bool operator <= ( Point3 const & p ) const
00426 {
00427 return (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00428 (_v[1]!=p._v[1])?(_v[1]< p._v[1]):
00429 (_v[0]<=p._v[0]);
00430 }
00431 inline bool operator >= ( Point3 const & p ) const
00432 {
00433 return (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00434 (_v[1]!=p._v[1])?(_v[1]> p._v[1]):
00435 (_v[0]>=p._v[0]);
00436 }
00437
00438
00439 inline Point3 operator - () const
00440 {
00441 return Point3<P3ScalarType> ( -_v[0], -_v[1], -_v[2] );
00442 }
00444
00445 };
00446
00447
00448 template <class P3ScalarType>
00449 inline P3ScalarType Angle( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 )
00450 {
00451 P3ScalarType w = p1.Norm()*p2.Norm();
00452 if(w==0) return -1;
00453 P3ScalarType t = (p1*p2)/w;
00454 if(t>1) t = 1;
00455 else if(t<-1) t = -1;
00456 return (P3ScalarType) acos(t);
00457 }
00458
00459
00460 template <class P3ScalarType>
00461 inline P3ScalarType AngleN( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 )
00462 {
00463 P3ScalarType w = p1*p2;
00464 if(w>1)
00465 w = 1;
00466 else if(w<-1)
00467 w=-1;
00468 return (P3ScalarType) acos(w);
00469 }
00470
00471
00472 template <class P3ScalarType>
00473 inline P3ScalarType Norm( Point3<P3ScalarType> const & p )
00474 {
00475 return p.Norm();
00476 }
00477
00478 template <class P3ScalarType>
00479 inline P3ScalarType SquaredNorm( Point3<P3ScalarType> const & p )
00480 {
00481 return p.SquaredNorm();
00482 }
00483
00484 template <class P3ScalarType>
00485 inline Point3<P3ScalarType> & Normalize( Point3<P3ScalarType> & p )
00486 {
00487 p.Normalize();
00488 return p;
00489 }
00490
00491 template <class P3ScalarType>
00492 inline P3ScalarType Distance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
00493 {
00494 return (p1-p2).Norm();
00495 }
00496
00497 template <class P3ScalarType>
00498 inline P3ScalarType SquaredDistance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
00499 {
00500 return (p1-p2).SquaredNorm();
00501 }
00502
00503 template <class P3ScalarType>
00504 P3ScalarType ApproximateGeodesicDistance(const Point3<P3ScalarType>& p0, const Point3<P3ScalarType>& n0,
00505 const Point3<P3ScalarType>& p1, const Point3<P3ScalarType>& n1)
00506 {
00507 Point3<P3ScalarType> V(p0-p1);
00508 V.Normalize();
00509 const P3ScalarType C0 = V*n0;
00510 const P3ScalarType C1 = V*n1;
00511 const P3ScalarType De = Distance(p0,p1);
00512 if(fabs(C0-C1)<0.0001) return De/sqrt(1-C0*C1);
00513 const P3ScalarType Dg = ((asin(C0) - asin(C1))/(C0-C1));
00514 return Dg*De;
00515 }
00516
00517
00518
00519
00520
00521 template<class P3ScalarType>
00522 double stable_dot ( Point3<P3ScalarType> const & p0, Point3<P3ScalarType> const & p1 )
00523 {
00524 P3ScalarType k0 = p0._v[0]*p1._v[0];
00525 P3ScalarType k1 = p0._v[1]*p1._v[1];
00526 P3ScalarType k2 = p0._v[2]*p1._v[2];
00527
00528 int exp0,exp1,exp2;
00529
00530 frexp( double(k0), &exp0 );
00531 frexp( double(k1), &exp1 );
00532 frexp( double(k2), &exp2 );
00533
00534 if( exp0<exp1 )
00535 {
00536 if(exp0<exp2)
00537 return (k1+k2)+k0;
00538 else
00539 return (k0+k1)+k2;
00540 }
00541 else
00542 {
00543 if(exp1<exp2)
00544 return(k0+k2)+k1;
00545 else
00546 return (k0+k1)+k2;
00547 }
00548 }
00549
00550
00551
00553 template<class P3ScalarType>
00554 P3ScalarType PSDist( const Point3<P3ScalarType> & p,
00555 const Point3<P3ScalarType> & v1,
00556 const Point3<P3ScalarType> & v2,
00557 Point3<P3ScalarType> & q )
00558 {
00559 Point3<P3ScalarType> e = v2-v1;
00560 P3ScalarType t = ((p-v1)*e)/e.SquaredNorm();
00561 if(t<0) t = 0;
00562 else if(t>1) t = 1;
00563 q = v1+e*t;
00564 return Distance(p,q);
00565 }
00566
00567
00568 template <class P3ScalarType>
00569 void GetUV( Point3<P3ScalarType> &n,Point3<P3ScalarType> &u, Point3<P3ScalarType> &v, Point3<P3ScalarType> up=(Point3<P3ScalarType>(0,1,0)) )
00570 {
00571 n.Normalize();
00572 const double LocEps=double(1e-7);
00573 u=n^up;
00574 double len = u.Norm();
00575 if(len < LocEps)
00576 {
00577 if(fabs(n[0])<fabs(n[1])){
00578 if(fabs(n[0])<fabs(n[2])) up=Point3<P3ScalarType>(1,0,0);
00579 else up=Point3<P3ScalarType>(0,0,1);
00580 }else {
00581 if(fabs(n[1])<fabs(n[2])) up=Point3<P3ScalarType>(0,1,0);
00582 else up=Point3<P3ScalarType>(0,0,1);
00583 }
00584 u=n^up;
00585 }
00586 u.Normalize();
00587 v=n^u;
00588 v.Normalize();
00589 }
00590
00591
00592 template <class SCALARTYPE>
00593 inline Point3<SCALARTYPE> Abs(const Point3<SCALARTYPE> & p) {
00594 return (Point3<SCALARTYPE>(math::Abs(p[0]), math::Abs(p[1]), math::Abs(p[2])));
00595 }
00596
00597 template <class SCALARTYPE>
00598 inline Point3<SCALARTYPE> LowClampToZero(const Point3<SCALARTYPE> & p) {
00599 return (Point3<SCALARTYPE>(std::max(p[0], (SCALARTYPE)0), std::max(p[1], (SCALARTYPE)0), std::max(p[2], (SCALARTYPE)0)));
00600 }
00601
00602 typedef Point3<short> Point3s;
00603 typedef Point3<int> Point3i;
00604 typedef Point3<float> Point3f;
00605 typedef Point3<double> Point3d;
00606
00609 }
00610
00611 #endif
00612