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 #ifndef __VCGLIB_POINT
00056 #define __VCGLIB_POINT
00057
00058 #include <assert.h>
00059 #include <vcg/math/base.h>
00060 #include <vcg/space/space.h>
00061
00062 namespace vcg {
00063
00064 namespace ndim{
00065
00066
00067
00068
00069
00079 template <int N, class S>
00080 class Point
00081 {
00082 public:
00083 typedef S ScalarType;
00084 typedef VoidType ParamType;
00085 typedef Point<N,S> PointType;
00086 enum {Dimension=N};
00087
00088
00089 protected:
00091 S _v[N];
00092
00093 public:
00094
00096
00101 inline Point () { };
00102
00103
00106 inline S Ext( const int i ) const
00107 {
00108 if(i>=0 && i<=N) return _v[i];
00109 else return 0;
00110 }
00111
00113 template <int N2, class S2>
00114 inline void Import( const Point<N2,S2> & b )
00115 {
00116 _v[0] = ScalarType(b[0]);
00117 _v[1] = ScalarType(b[1]);
00118 if (N>2) { if (N2>2) _v[2] = ScalarType(b[2]); else _v[2] = 0;};
00119 if (N>3) { if (N2>3) _v[3] = ScalarType(b[3]); else _v[3] = 0;};
00120 }
00121
00123 template <int N2, class S2>
00124 static inline PointType Construct( const Point<N2,S2> & b )
00125 {
00126 PointType p; p.Import(b);
00127 return p;
00128 }
00129
00131 template <class S2>
00132 inline void ImportHomo( const Point<N-1,S2> & b )
00133 {
00134 _v[0] = ScalarType(b[0]);
00135 _v[1] = ScalarType(b[1]);
00136 if (N>2) { _v[2] = ScalarType(_v[2]); };
00137 _v[N-1] = 1.0;
00138 }
00139
00141 template <int N2, class S2>
00142 static inline PointType Construct( const Point<N-1,S2> & b )
00143 {
00144 PointType p; p.ImportHomo(b);
00145 return p;
00146 }
00147
00149
00151
00155 inline S & operator [] ( const int i )
00156 {
00157 assert(i>=0 && i<N);
00158 return _v[i];
00159 }
00160 inline const S & operator [] ( const int i ) const
00161 {
00162 assert(i>=0 && i<N);
00163 return _v[i];
00164 }
00165 inline const S &X() const { return _v[0]; }
00166 inline const S &Y() const { return _v[1]; }
00167 inline const S &Z() const { static_assert(N>2); return _v[2]; }
00171 inline const S &W() const { return _v[N-1]; }
00172 inline S &X() { return _v[0]; }
00173 inline S &Y() { return _v[1]; }
00174 inline S &Z() { static_assert(N>2); return _v[2]; }
00175 inline S &W() { return _v[N-1]; }
00176 inline const S * V() const
00177 {
00178 return _v;
00179 }
00180 inline S * V()
00181 {
00182 return _v;
00183 }
00184 inline S & V( const int i )
00185 {
00186 assert(i>=0 && i<N);
00187 return _v[i];
00188 }
00189 inline const S & V( const int i ) const
00190 {
00191 assert(i>=0 && i<N);
00192 return _v[i];
00193 }
00195
00196
00200
00201 inline void SetZero()
00202 {
00203 for(unsigned int ii = 0; ii < Dimension;++ii)
00204 V(ii) = S();
00205 }
00206
00207 inline PointType operator + ( PointType const & p) const
00208 {
00209 PointType res;
00210 for(unsigned int ii = 0; ii < Dimension;++ii)
00211 res[ii] = V(ii) + p[ii];
00212 return res;
00213 }
00214
00215 inline PointType operator - ( PointType const & p) const
00216 {
00217 PointType res;
00218 for(unsigned int ii = 0; ii < Dimension;++ii)
00219 res[ii] = V(ii) - p[ii];
00220 return res;
00221 }
00222
00223 inline PointType operator * ( const S s ) const
00224 {
00225 PointType res;
00226 for(unsigned int ii = 0; ii < Dimension;++ii)
00227 res[ii] = V(ii) * s;
00228 return res;
00229 }
00230
00231 inline PointType operator / ( const S s ) const
00232 {
00233 PointType res;
00234 for(unsigned int ii = 0; ii < Dimension;++ii)
00235 res[ii] = V(ii) / s;
00236 return res;
00237 }
00238
00239 inline PointType & operator += ( PointType const & p)
00240 {
00241 for(unsigned int ii = 0; ii < Dimension;++ii)
00242 V(ii) += p[ii];
00243 return *this;
00244 }
00245
00246 inline PointType & operator -= ( PointType const & p)
00247 {
00248 for(unsigned int ii = 0; ii < Dimension;++ii)
00249 V(ii) -= p[ii];
00250 return *this;
00251 }
00252
00253 inline PointType & operator *= ( const S s )
00254 {
00255 for(unsigned int ii = 0; ii < Dimension;++ii)
00256 V(ii) *= s;
00257 return *this;
00258 }
00259
00260 inline PointType & operator /= ( const S s )
00261 {
00262 for(unsigned int ii = 0; ii < Dimension;++ii)
00263 V(ii) *= s;
00264 return *this;
00265 }
00266
00267 inline PointType operator - () const
00268 {
00269 PointType res;
00270 for(unsigned int ii = 0; ii < Dimension;++ii)
00271 res[ii] = - V(ii);
00272 return res;
00273 }
00275
00276
00279
00280 inline S operator * ( PointType const & p ) const;
00281
00283 inline S StableDot ( const PointType & p ) const;
00284
00286
00288
00292
00293 inline S Norm() const;
00295 template <class PT> static S Norm(const PT &p );
00297 inline S SquaredNorm() const;
00299 template <class PT> static S SquaredNorm(const PT &p );
00301 inline PointType & Normalize();
00303 template <class PT> static PointType & Normalize(const PT &p);
00305 inline PointType & HomoNormalize();
00306
00308 inline S NormInfinity() const;
00310 inline S NormOne() const;
00311
00313
00314
00315 inline S operator % ( PointType const & p ) const;
00316
00318 inline S Sum() const;
00320 inline S Max() const;
00322 inline S Min() const;
00324 inline int MaxI() const;
00326 inline int MinI() const;
00327
00328
00330 inline PointType & Scale( const PointType & p );
00331
00332
00334 void ToPolar( S & ro, S & tetha, S & fi ) const
00335 {
00336 ro = Norm();
00337 tetha = (S)atan2( _v[1], _v[0] );
00338 fi = (S)acos( _v[2]/ro );
00339 }
00340
00342
00347 inline bool operator == ( PointType const & p ) const;
00348 inline bool operator != ( PointType const & p ) const;
00349 inline bool operator < ( PointType const & p ) const;
00350 inline bool operator > ( PointType const & p ) const;
00351 inline bool operator <= ( PointType const & p ) const;
00352 inline bool operator >= ( PointType const & p ) const;
00354
00356
00362 inline PointType LocalToGlobal(ParamType p) const{
00363 return *this; }
00364
00365 inline ParamType GlobalToLocal(PointType ) const{
00366 return ParamType(); }
00368
00369 };
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 template <class S>
00380 class Point2 : public Point<2,S> {
00381 public:
00382 typedef S ScalarType;
00383 typedef Point2 PointType;
00384 using Point<2,S>::_v;
00385 using Point<2,S>::V;
00386 using Point<2,S>::W;
00387
00389
00391
00392 inline Point2 (){}
00393
00395 inline Point2 ( const S a, const S b){
00396 _v[0]=a; _v[1]=b; };
00397
00400 inline Point2 operator ~ () const {
00401 return Point2 ( -_v[2], _v[1] );
00402 }
00403
00405 inline ScalarType &Angle(){
00406 return math::Atan2(_v[1],_v[0]);}
00407
00409 inline Point2 & ToPolar(){
00410 ScalarType t = Angle();
00411 _v[0] = Norm();
00412 _v[1] = t;
00413 return *this;}
00414
00416 inline Point2 & ToCartesian() {
00417 ScalarType l = _v[0];
00418 _v[0] = (ScalarType)(l*math::Cos(_v[1]));
00419 _v[1] = (ScalarType)(l*math::Sin(_v[1]));
00420 return *this;}
00421
00423 inline Point2 & Rotate( const ScalarType rad ){
00424 ScalarType t = _v[0];
00425 ScalarType s = math::Sin(rad);
00426 ScalarType c = math::Cos(rad);
00427 _v[0] = _v[0]*c - _v[1]*s;
00428 _v[1] = t *s + _v[1]*c;
00429 return *this;}
00430
00432
00434
00436 inline void Zero(){
00437 _v[0]=0; _v[1]=0; };
00438
00439 inline Point2 ( const S nv[2] ){
00440 _v[0]=nv[0]; _v[1]=nv[1]; };
00441
00442 inline Point2 operator + ( Point2 const & p) const {
00443 return Point2( _v[0]+p._v[0], _v[1]+p._v[1]); }
00444
00445 inline Point2 operator - ( Point2 const & p) const {
00446 return Point2( _v[0]-p._v[0], _v[1]-p._v[1]); }
00447
00448 inline Point2 operator * ( const S s ) const {
00449 return Point2( _v[0]*s, _v[1]*s ); }
00450
00451 inline Point2 operator / ( const S s ) const {
00452 S t=1.0/s;
00453 return Point2( _v[0]*t, _v[1]*t ); }
00454
00455 inline Point2 operator - () const {
00456 return Point2 ( -_v[0], -_v[1] ); }
00457
00458 inline Point2 & operator += ( Point2 const & p ) {
00459 _v[0] += p._v[0]; _v[1] += p._v[1]; return *this; }
00460
00461 inline Point2 & operator -= ( Point2 const & p ) {
00462 _v[0] -= p._v[0]; _v[1] -= p._v[1]; return *this; }
00463
00464 inline Point2 & operator *= ( const S s ) {
00465 _v[0] *= s; _v[1] *= s; return *this; }
00466
00467 inline Point2 & operator /= ( const S s ) {
00468 S t=1.0/s; _v[0] *= t; _v[1] *= t; return *this; }
00469
00470 inline S Norm() const {
00471 return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] );}
00472
00473 template <class PT> static S Norm(const PT &p ) {
00474 return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) );}
00475
00476 inline S SquaredNorm() const {
00477 return ( _v[0]*_v[0] + _v[1]*_v[1] );}
00478
00479 template <class PT> static S SquaredNorm(const PT &p ) {
00480 return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) );}
00481
00482 inline S operator * ( Point2 const & p ) const {
00483 return ( _v[0]*p._v[0] + _v[1]*p._v[1]) ; }
00484
00485 inline bool operator == ( Point2 const & p ) const {
00486 return _v[0]==p._v[0] && _v[1]==p._v[1] ;}
00487
00488 inline bool operator != ( Point2 const & p ) const {
00489 return _v[0]!=p._v[0] || _v[1]!=p._v[1] ;}
00490
00491 inline bool operator < ( Point2 const & p ) const{
00492 return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<p._v[0]); }
00493
00494 inline bool operator > ( Point2 const & p ) const {
00495 return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); }
00496
00497 inline bool operator <= ( Point2 const & p ) {
00498 return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); }
00499
00500 inline bool operator >= ( Point2 const & p ) const {
00501 return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); }
00502
00503 inline Point2 & Normalize() {
00504 PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n;} return *this;}
00505
00506 inline Point2 & HomoNormalize(){
00507 if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;}
00508
00509 inline S NormInfinity() const {
00510 return math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ); }
00511
00512 inline S NormOne() const {
00513 return math::Abs(_v[0])+ math::Abs(_v[1]);}
00514
00515 inline S operator % ( Point2 const & p ) const {
00516 return _v[0] * p._v[1] - _v[1] * p._v[0]; }
00517
00518 inline S Sum() const {
00519 return _v[0]+_v[1];}
00520
00521 inline S Max() const {
00522 return math::Max( _v[0], _v[1] ); }
00523
00524 inline S Min() const {
00525 return math::Min( _v[0], _v[1] ); }
00526
00527 inline int MaxI() const {
00528 return (_v[0] < _v[1]) ? 1:0; };
00529
00530 inline int MinI() const {
00531 return (_v[0] > _v[1]) ? 1:0; };
00532
00533 inline PointType & Scale( const PointType & p ) {
00534 _v[0] *= p._v[0]; _v[1] *= p._v[1]; return *this; }
00535
00536 inline S StableDot ( const PointType & p ) const {
00537 return _v[0]*p._v[0] +_v[1]*p._v[1]; }
00539
00540 };
00541
00542 template <typename S>
00543 class Point3 : public Point<3,S> {
00544 public:
00545 typedef S ScalarType;
00546 typedef Point3<S> PointType;
00547 using Point<3,S>::_v;
00548 using Point<3,S>::V;
00549 using Point<3,S>::W;
00550
00551
00553
00555
00556 inline Point3 ():Point<3,S>(){}
00558 inline Point3 ( const S a, const S b, const S c){
00559 _v[0]=a; _v[1]=b; _v[2]=c; };
00560
00562 inline PointType operator ^ ( PointType const & p ) const {
00563 return Point3 (
00564 _v[1]*p._v[2] - _v[2]*p._v[1],
00565 _v[2]*p._v[0] - _v[0]*p._v[2],
00566 _v[0]*p._v[1] - _v[1]*p._v[0] );
00567 }
00569
00571
00573 inline void Zero(){
00574 _v[0]=0; _v[1]=0; _v[2]=0; };
00575
00576 inline Point3 ( const S nv[3] ){
00577 _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; };
00578
00579 inline Point3 operator + ( Point3 const & p) const{
00580 return Point3( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2]); }
00581
00582 inline Point3 operator - ( Point3 const & p) const {
00583 return Point3( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2]); }
00584
00585 inline Point3 operator * ( const S s ) const {
00586 return Point3( _v[0]*s, _v[1]*s , _v[2]*s ); }
00587
00588 inline Point3 operator / ( const S s ) const {
00589 S t=1.0/s;
00590 return Point3( _v[0]*t, _v[1]*t , _v[2]*t ); }
00591
00592 inline Point3 operator - () const {
00593 return Point3 ( -_v[0], -_v[1] , -_v[2] ); }
00594
00595 inline Point3 & operator += ( Point3 const & p ) {
00596 _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; return *this; }
00597
00598 inline Point3 & operator -= ( Point3 const & p ) {
00599 _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; return *this; }
00600
00601 inline Point3 & operator *= ( const S s ) {
00602 _v[0] *= s; _v[1] *= s; _v[2] *= s; return *this; }
00603
00604 inline Point3 & operator /= ( const S s ) {
00605 S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; return *this; }
00606
00607 inline S Norm() const {
00608 return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );}
00609
00610 template <class PT> static S Norm(const PT &p ) {
00611 return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );}
00612
00613 inline S SquaredNorm() const {
00614 return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );}
00615
00616 template <class PT> static S SquaredNorm(const PT &p ) {
00617 return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );}
00618
00619 inline S operator * ( PointType const & p ) const {
00620 return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2]) ; }
00621
00622 inline bool operator == ( PointType const & p ) const {
00623 return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] ;}
00624
00625 inline bool operator != ( PointType const & p ) const {
00626 return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] ;}
00627
00628 inline bool operator < ( PointType const & p ) const{
00629 return (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00630 (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<p._v[0]); }
00631
00632 inline bool operator > ( PointType const & p ) const {
00633 return (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00634 (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); }
00635
00636 inline bool operator <= ( PointType const & p ) {
00637 return (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00638 (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); }
00639
00640 inline bool operator >= ( PointType const & p ) const {
00641 return (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00642 (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); }
00643
00644 inline PointType & Normalize() {
00645 S n = Norm();
00646 if(n!=0.0) {
00647 n=S(1.0)/n;
00648 _v[0]*=n; _v[1]*=n; _v[2]*=n; }
00649 return *this;}
00650
00651 inline PointType & HomoNormalize(){
00652 if (_v[2]!=0.0) { _v[0] /= W(); _v[1] /= W(); W()=1.0; }
00653 return *this;}
00654
00655 inline S NormInfinity() const {
00656 return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
00657 math::Abs(_v[3]) ); }
00658
00659 inline S NormOne() const {
00660 return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]));}
00661
00662 inline S operator % ( PointType const & p ) const {
00663 S t = (*this)*p;
00664 return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );};
00665
00666 inline S Sum() const {
00667 return _v[0]+_v[1]+_v[2];}
00668
00669 inline S Max() const {
00670 return math::Max( math::Max( _v[0], _v[1] ), _v[2] ); }
00671
00672 inline S Min() const {
00673 return math::Min( math::Min( _v[0], _v[1] ), _v[2] ); }
00674
00675 inline int MaxI() const {
00676 int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; return i;};
00677
00678 inline int MinI() const {
00679 int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; return i;};
00680
00681 inline PointType & Scale( const PointType & p ) {
00682 _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; return *this; }
00683
00684 inline S StableDot ( const PointType & p ) const {
00685 S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2];
00686 int exp0,exp1,exp2;
00687 frexp( double(k0), &exp0 );
00688 frexp( double(k1), &exp1 );
00689 frexp( double(k2), &exp2 );
00690 if( exp0<exp1 )
00691 if(exp0<exp2) return (k1+k2)+k0; else return (k0+k1)+k2;
00692 else
00693 if(exp1<exp2) return (k0+k2)+k1; else return (k0+k1)+k2;
00694 }
00696
00697 };
00698
00699 template <typename S>
00700 class Point4 : public Point<4,S> {
00701 public:
00702 typedef S ScalarType;
00703 typedef Point4<S> PointType;
00704 using Point<3,S>::_v;
00705 using Point<3,S>::V;
00706 using Point<3,S>::W;
00707
00709
00710
00711 inline Point4 (){}
00712
00714
00715 inline Point4 ( const S a, const S b, const S c, const S d){
00716 _v[0]=a; _v[1]=b; _v[2]=c; _v[3]=d; };
00718
00720 inline void Zero(){
00721 _v[0]=0; _v[1]=0; _v[2]=0; _v[3]=0; };
00722
00723 inline Point4 ( const S nv[4] ){
00724 _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; _v[3]=nv[3]; };
00725
00726 inline Point4 operator + ( Point4 const & p) const {
00727 return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] ); }
00728
00729 inline Point4 operator - ( Point4 const & p) const {
00730 return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] ); }
00731
00732 inline Point4 operator * ( const S s ) const {
00733 return Point4( _v[0]*s, _v[1]*s , _v[2]*s , _v[3]*s ); }
00734
00735 inline PointType operator ^ ( PointType const & p ) const {
00736 assert(0);
00737 return *this;
00738 }
00739
00740 inline Point4 operator / ( const S s ) const {
00741 S t=1.0/s;
00742 return Point4( _v[0]*t, _v[1]*t , _v[2]*t , _v[3]*t ); }
00743
00744 inline Point4 operator - () const {
00745 return Point4 ( -_v[0], -_v[1] , -_v[2] , -_v[3] ); }
00746
00747 inline Point4 & operator += ( Point4 const & p ) {
00748 _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; _v[3] += p._v[3]; return *this; }
00749
00750 inline Point4 & operator -= ( Point4 const & p ) {
00751 _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; _v[3] -= p._v[3]; return *this; }
00752
00753 inline Point4 & operator *= ( const S s ) {
00754 _v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s; return *this; }
00755
00756 inline Point4 & operator /= ( const S s ) {
00757 S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; _v[3] *= t; return *this; }
00758
00759 inline S Norm() const {
00760 return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );}
00761
00762 template <class PT> static S Norm(const PT &p ) {
00763 return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );}
00764
00765 inline S SquaredNorm() const {
00766 return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );}
00767
00768 template <class PT> static S SquaredNorm(const PT &p ) {
00769 return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );}
00770
00771 inline S operator * ( PointType const & p ) const {
00772 return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3] ); }
00773
00774 inline bool operator == ( PointType const & p ) const {
00775 return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];}
00776
00777 inline bool operator != ( PointType const & p ) const {
00778 return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];}
00779
00780 inline bool operator < ( PointType const & p ) const{
00781 return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00782 (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<p._v[0]); }
00783
00784 inline bool operator > ( PointType const & p ) const {
00785 return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00786 (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); }
00787
00788 inline bool operator <= ( PointType const & p ) {
00789 return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]):
00790 (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); }
00791
00792 inline bool operator >= ( PointType const & p ) const {
00793 return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]):
00794 (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); }
00795
00796 inline PointType & Normalize() {
00797 PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n; _v[2]*=n; _v[3]*=n; }
00798 return *this;};
00799
00800 template <class PT> PointType & Normalize(const PT &p){
00801 PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; V(3)*=n; }
00802 return *this;};
00803
00804 inline PointType & HomoNormalize(){
00805 if (_v[3]!=0.0) { _v[0] /= W(); _v[1] /= W(); _v[2] /= W(); W()=1.0; }
00806 return *this;};
00807
00808 inline S NormInfinity() const {
00809 return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ),
00810 math::Max( math::Abs(_v[2]), math::Abs(_v[3]) ) ); }
00811
00812 inline S NormOne() const {
00813 return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]),math::Abs(_v[3]));}
00814
00815 inline S operator % ( PointType const & p ) const {
00816 S t = (*this)*p;
00817 return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );};
00818
00819 inline S Sum() const {
00820 return _v[0]+_v[1]+_v[2]+_v[3];}
00821
00822 inline S Max() const {
00823 return math::Max( math::Max( _v[0], _v[1] ), math::Max( _v[2], _v[3] )); }
00824
00825 inline S Min() const {
00826 return math::Min( math::Min( _v[0], _v[1] ), math::Min( _v[2], _v[3] )); }
00827
00828 inline int MaxI() const {
00829 int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; if (_v[i] < _v[3]) i=3;
00830 return i;};
00831
00832 inline int MinI() const {
00833 int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; if (_v[i] > _v[3]) i=3;
00834 return i;};
00835
00836 inline PointType & Scale( const PointType & p ) {
00837 _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; _v[3] *= p._v[3]; return *this; }
00838
00839 inline S StableDot ( const PointType & p ) const {
00840 S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2], k3=_v[3]*p._v[3];
00841 int exp0,exp1,exp2,exp3;
00842 frexp( double(k0), &exp0 );frexp( double(k1), &exp1 );
00843 frexp( double(k2), &exp2 );frexp( double(k3), &exp3 );
00844 if (exp0>exp1) { std::swap(k0,k1); std::swap(exp0,exp1); }
00845 if (exp2>exp3) { std::swap(k2,k3); std::swap(exp2,exp3); }
00846 if (exp0>exp2) { std::swap(k0,k2); std::swap(exp0,exp2); }
00847 if (exp1>exp3) { std::swap(k1,k3); std::swap(exp1,exp3); }
00848 if (exp2>exp3) { std::swap(k2,k3); std::swap(exp2,exp3); }
00849 return ( (k0 + k1) + k2 ) +k3; }
00850
00852 };
00853
00854
00855 template <class S>
00856 inline S Angle( Point3<S> const & p1, Point3<S> const & p2 )
00857 {
00858 S w = p1.Norm()*p2.Norm();
00859 if(w==0) return -1;
00860 S t = (p1*p2)/w;
00861 if(t>1) t = 1;
00862 else if(t<-1) t = -1;
00863 return (S) acos(t);
00864 }
00865
00866
00867 template <class S>
00868 inline S AngleN( Point3<S> const & p1, Point3<S> const & p2 )
00869 {
00870 S w = p1*p2;
00871 if(w>1)
00872 w = 1;
00873 else if(w<-1)
00874 w=-1;
00875 return (S) acos(w);
00876 }
00877
00878
00879 template <int N,class S>
00880 inline S Norm( Point<N,S> const & p )
00881 {
00882 return p.Norm();
00883 }
00884
00885 template <int N,class S>
00886 inline S SquaredNorm( Point<N,S> const & p )
00887 {
00888 return p.SquaredNorm();
00889 }
00890
00891 template <int N,class S>
00892 inline Point<N,S> & Normalize( Point<N,S> & p )
00893 {
00894 p.Normalize();
00895 return p;
00896 }
00897
00898 template <int N, class S>
00899 inline S Distance( Point<N,S> const & p1,Point<N,S> const & p2 )
00900 {
00901 return (p1-p2).Norm();
00902 }
00903
00904 template <int N, class S>
00905 inline S SquaredDistance( Point<N,S> const & p1,Point<N,S> const & p2 )
00906 {
00907 return (p1-p2).SquaredNorm();
00908 }
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 typedef Point2<short> Point2s;
00934 typedef Point2<int> Point2i;
00935 typedef Point2<float> Point2f;
00936 typedef Point2<double> Point2d;
00937 typedef Point2<short> Vector2s;
00938 typedef Point2<int> Vector2i;
00939 typedef Point2<float> Vector2f;
00940 typedef Point2<double> Vector2d;
00941
00942 typedef Point3<short> Point3s;
00943 typedef Point3<int> Point3i;
00944 typedef Point3<float> Point3f;
00945 typedef Point3<double> Point3d;
00946 typedef Point3<short> Vector3s;
00947 typedef Point3<int> Vector3i;
00948 typedef Point3<float> Vector3f;
00949 typedef Point3<double> Vector3d;
00950
00951
00952 typedef Point4<short> Point4s;
00953 typedef Point4<int> Point4i;
00954 typedef Point4<float> Point4f;
00955 typedef Point4<double> Point4d;
00956 typedef Point4<short> Vector4s;
00957 typedef Point4<int> Vector4i;
00958 typedef Point4<float> Vector4f;
00959 typedef Point4<double> Vector4d;
00960
00963
00964 template<unsigned int N,typename S>
00965 struct PointBase : Point<N,S>
00966 {
00967 PointBase()
00968 :Point<N,S>()
00969 {
00970 }
00971 };
00972
00973 }
00974 }
00975 #endif
00976