00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #ifndef INCLUDE_TRIGO_H
00024 #define INCLUDE_TRIGO_H
00025
00026 #include <math.h>
00027 #include <windows.h>
00028
00029 #define PI 3.1415926535f
00030 #define DOUBLE_PI (PI*2.0f)
00031 #define HALF_PI (PI/2.0f)
00032 #define PRECISION 0.0001 // pour les calculs de IsOnXXXXX() : valeur par defaut
00033 #define DEGTORAD(ang) ((ang) * PI / 180.0)
00034 #define RADTODEG(ang) ((ang) * 180.0/ PI)
00035
00036 double Bound2_PI(double angle);
00037 BOOL GetTrigoSens(POINT *pt);
00038 BOOL GetTrigoSens(POINT *pt,int nbPoints);
00039 void ChangeTrigoSens(POINT *pt,int nbPoints);
00040 int GetNearExp2(int num);
00041
00042 template <class T> class Point3D;
00046 template <class T> class Point1D
00047 {
00048 public:
00049 T value;
00050
00051 public:
00052 Point1D() { Zero(); }
00053 Point1D(T _value) { value=_value; }
00054 void Zero() { value=0; }
00055 BOOL operator==(Point1D<T> &src) { return (value==src.value); }
00056 void operator=(Point1D<T> &src) { value=src.value; }
00057 void operator=(T _value) { value=_value; }
00058
00059
00060
00061
00062 T operator+(T _value) { T t; t = value+_value; return t; }
00063 T operator-(T _value) { T t; t = value-_value; return t; }
00064 double operator/(double coef) { return value/coef; }
00065 double operator*(double coef) { return value*coef; }
00066 operator T() const { return value; }
00067 double LinearInterpolation(T value1,T value2,double alpha);
00068 };
00069
00073 template <class T> class Point2D
00074 {
00075 public:
00076 T x;
00077 T y;
00078
00079 public:
00080 Point2D() { Zero(); }
00081 Point2D(T _x,T _y) { Set(_x,_y); }
00082 void Set (T _x,T _y) { x=_x; y=_y; }
00083 void Zero() { x=0; y=0; }
00084 BOOL operator==(Point2D<T> &src) { return (x==src.x)&&(y==src.y); }
00085 BOOL operator!=(Point2D<T> &src) { return !((x==src.x)&&(y==src.y)); }
00086 void operator=(Point3D<T> &src);
00087 void operator=(Point2D<T> &src) { x=src.x; y=src.y; }
00088 void operator+=(Point2D<T> &src) { x+=src.x; y+=src.y; }
00089 Point2D<T> operator-(Point2D<T> &src);
00090 Point2D<T> operator+(Point2D<T> &src);
00091 Point2D<T> operator*(double coef);
00092 Point2D<T> operator/(double coef);
00093 void operator/=(double coef) { x/=coef; y/=coef; }
00094 void operator*=(double coef) { x*=coef; y*=coef; }
00095 double Power() { return sqrt(x*x+y*y); }
00096
00097 BOOL IsOnSegment(Point2D<T> &a,Point2D<T> &b,double *alpha=NULL);
00098 BOOL IsOnLine(Point2D<T> &a,Point2D<T> &b,double *alpha=NULL,double precision=PRECISION);
00099 BOOL IsOnTriangle(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,double *alphaBC,double *alphaAPP,Point2D<T> *pp=NULL);
00100 BOOL IsOnQuadrilatere(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *alphaX=NULL,double *alphaY=NULL);
00101 BOOL IsOnRectangle(Point2D<T> &a,Point2D<T> &c,double *alphaX=NULL,double *alphaY=NULL);
00102
00103 BOOL GetRelativePtOnQuadrilatere(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *deltaX,double *deltaY);
00104 BOOL GetRelativePtOn2Lines(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *alpha);
00105
00106 void ToNormalVector(BOOL asTrigo=TRUE);
00107 };
00108
00109
00110 #include "include/quaternion.h"
00111
00116 template <class T> class Point3D
00117 {
00118 public:
00119 T x;
00120 T y;
00121 T z;
00122
00123 public:
00124 Point3D() { Zero(); }
00125 Point3D(T _x,T _y,T _z) { Set(_x,_y,_z); }
00126
00127 void Set (T _x,T _y,T _z=0) { x=_x; y=_y; z=_z; }
00128 void Zero() { x=0; y=0; z=0; }
00129 BOOL IsEqual(T _x,T _y,T _z) { return (x==_x)&&(y==_y)&&(z==_z); }
00130 BOOL operator==(Point3D<T> &src) { return (x==src.x)&&(y==src.y)&&(z==src.z); }
00131 void operator=(Point3D<T> &src);
00132 void Add(T _x,T _y,T _z);
00133 void operator+=(Point3D<T> &src);
00134 void operator/=(double divide);
00135
00136 void glRotated(double ratio);
00137 void glRotated();
00138 void glTranslated(double ratio);
00139 void glTranslated();
00140 void glRasterPos() { glRasterPos3d(x,y,z); }
00141 void glScale() { glScaled(x,y,z); }
00142
00143 double Power() { return sqrt(x*x+y*y+z*z); }
00144 Point3D<T> QuaternionRotate (Point3D<T> &rotate);
00145 void operator=(Point2D<T> &src);
00146 BOOL IsOnTriangle(Point3D<T> &a,Point3D<T> &b,Point3D<T> &c);
00147 BOOL IsNotNull() { return (x||y||z)?TRUE:FALSE; }
00148 };
00149
00161 template <class T>
00162 class LinearEqu2D
00163 {
00164 private:
00165 void Compute()
00166 {
00167 a=pt1.y-pt2.y;
00168 b=pt2.x-pt1.x;
00169 c=-(pt1.x*a+pt1.y*b);
00170 }
00171
00172 double a,b,c;
00173 Point2D<T> pt1,pt2;
00174
00175 public:
00176 LinearEqu2D() { Zero(); }
00177 LinearEqu2D(Point2D<T> &_pt1,Point2D<T> &_pt2) { Set(_pt1,_pt2); }
00178
00179 void Zero()
00180 {
00181 pt1.Zero();
00182 pt2.Zero();
00183 a=b=c=0;
00184 }
00185
00186 void Set(Point2D<T> &_pt1,Point2D<T> &_pt2)
00187 {
00188 pt1=_pt1;
00189 pt2=_pt2;
00190 Compute();
00191 }
00192
00193 BOOL IsPoint() { return a||b?TRUE:FALSE; }
00194 BOOL IsVertical() { return a&&!b?TRUE:FALSE; }
00195 BOOL IsHorizontal() { return !a&&b?TRUE:FALSE; }
00196
00197 BOOL GetCrossPtFromVertical(T x,Point2D<T> *pt=NULL)
00198 {
00199 Point2D<T> ptv1(x,0);
00200 Point2D<T> ptv2(x,10);
00201 LinearEqu2D<T> vertEqu(ptv1,ptv2);
00202 return GetCrossPtFromLine(vertEqu,pt);
00203 }
00204
00205 BOOL GetCrossPtFromHorizontal(T y,Point2D<T> *pt=NULL)
00206 {
00207 Point2D<T> pth1(0,y);
00208 Point2D<T> pth2(10,y);
00209 LinearEqu2D<T> horiEqu(pth1,pth2);
00210 return GetCrossPtFromLine(horiEqu,pt);
00211 }
00231 BOOL GetCrossPtFromLine(LinearEqu2D<T> &equ,Point2D<T> *pt=NULL)
00232 {
00233 Point2D<T> _pt;
00234 if (!pt) pt=&_pt;
00235 if (!ComputePtFromeLine(*this,equ,pt))
00236 return ComputePtFromeLine(equ,*this,pt);
00237 else return TRUE;
00238 return TRUE;
00239 }
00240
00241 private:
00242 BOOL ComputePtFromeLine(LinearEqu2D<T> &equ1,LinearEqu2D<T> &equ2,Point2D<T> *pt)
00243 {
00244 T denominateur = ((equ2.a*equ1.b)-(equ1.a*equ2.b));
00245 if (!denominateur) return FALSE;
00246 pt->y = ((equ1.a*equ2.c)-(equ2.a*equ1.c))/denominateur;
00247 if (!equ2.a) return FALSE;
00248 pt->x = ((equ2.b*pt->y)+equ2.c)/-equ2.a;
00249 return TRUE;
00250 }
00251 };
00252
00253
00254
00255 template <class T>
00256 double Point1D<T>::LinearInterpolation(T value1,T value2,double alpha)
00257 {
00258 value= value1+(double)(value2-value1)*alpha;
00259 return value;
00260 }
00261
00262
00263
00264 template <class T>
00265 Point2D<T> Point2D<T>::operator-(Point2D<T> &src)
00266 {
00267 Point2D<T> pt;
00268 pt.x=x-src.x;
00269 pt.y=y-src.y;
00270 return pt;
00271 }
00272
00273 template <class T>
00274 Point2D<T> Point2D<T>::operator+(Point2D<T> &src)
00275 {
00276 Point2D<T> pt;
00277 pt.x=x+src.x;
00278 pt.y=y+src.y;
00279 return pt;
00280 }
00281
00282 template <class T>
00283 Point2D<T> Point2D<T>::operator*(double coef)
00284 {
00285 Point2D<T> pt;
00286 pt.x=(T)(x*coef);
00287 pt.y=(T)(y*coef);
00288 return pt;
00289 }
00290
00291 template <class T>
00292 Point2D<T> Point2D<T>::operator/(double coef)
00293 {
00294 Point2D<T> pt;
00295 pt.x=(T)(x/coef);
00296 pt.y=(T)(y/coef);
00297 return pt;
00298 }
00299
00300 template <class T>
00301 void Point2D<T>::operator=(Point3D<T> &src)
00302 {
00303 x=src.x;
00304 y=src.y;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 template <class T>
00317 BOOL Point2D<T>::IsOnSegment(Point2D<T> &a,Point2D<T> &b,double *alpha)
00318 {
00319 double _alpha;
00320 if (!alpha) alpha=&_alpha;
00321 if (IsOnLine(a,b,alpha)) return ((*alpha>=0)&&(*alpha<=1))?TRUE:FALSE;
00322 return FALSE;
00323 }
00324
00325 template <class T>
00326 BOOL Point2D<T>::IsOnLine(Point2D<T> &a,Point2D<T> &b,double *alpha,double precision)
00327 {
00328 double dx = b.x-a.x;
00329 double dy = b.y-a.y;
00330 if (!dx&&!dy)
00331 {
00332 if (a==*this)
00333 {
00334 if (alpha) *alpha = 0;
00335 return TRUE;
00336 }
00337 return FALSE;
00338 }
00339
00340 double dxap = x-a.x;
00341 double dyap = y-a.y;
00342 double reste=dxap*dy-dyap*dx;
00343 if (fabs(reste)<=precision)
00344 {
00345 if (alpha)
00346 {
00347 if (dx) *alpha = dxap/dx;
00348 else if (dy) *alpha = dyap/dy;
00349 else *alpha = 0;
00350 }
00351 return TRUE;
00352 }
00353 return FALSE;
00354 }
00355
00356
00357
00358
00359
00360 template <class T>
00361 void Point2D<T>::ToNormalVector(BOOL asTrigo)
00362 {
00363 T temp = x;
00364 if (asTrigo)
00365 {
00366 x = -y;
00367 y = temp;
00368 }
00369 else
00370 {
00371 x = y;
00372 y = -temp;
00373 }
00374 }
00375
00392 template <class T>
00393 BOOL Point2D<T>::IsOnTriangle(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,double *alphaBC,double *alphaAPP,Point2D<T> *pp)
00394 {
00395 Point2D<T> _pp;
00396 Point1D<T> interpolation;
00397 double _alphaBC,_alphaAPP;
00398 if (!alphaAPP) alphaAPP=&_alphaAPP;
00399 if (!alphaBC) alphaBC=&_alphaBC;
00400 if (!pp) pp=&_pp;
00401
00402
00403 LinearEqu2D<T> equAP(a,*this);
00404 LinearEqu2D<T> equBC(b,c);
00405 if (!equAP.GetCrossPtFromLine(equBC,pp)) return FALSE;
00406
00407 if (!pp->IsOnSegment(b,c,alphaBC)) return FALSE;
00408
00409 if (!IsOnSegment(a,*pp,alphaAPP)) return FALSE;
00410 return TRUE;
00411 }
00412
00414
00415 template <class T>
00416 BOOL Point2D<T>::IsOnRectangle(Point2D<T> &a,Point2D<T> &c,double *alphaX,double *alphaY)
00417 {
00418 Point2D<T> b(c.x,a.y),Point2D<T> d(a.x,c.y);
00419 return IsOnQuadrilatere(a,b,c,d,alphaX,alphaY);
00420 }
00421
00423
00424 template <class T>
00425 BOOL Point2D<T>::IsOnQuadrilatere(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *alphaX,double *alphaY)
00426 {
00427 double _alphaX,_alphaY;
00428 if (!alphaX) _alphaX=&alphaX;
00429 if (!alphaY) _alphaY=&alphaY;
00430 BOOL res = GetRelativePtOnQuadrilatere(a,b,c,d,&_alphaX,&_alphaY);
00431 return (!res||*alphaX<0||*alphaY<0)?FALSE:TRUE;
00432 }
00433
00459 template <class T>
00460 BOOL Point2D<T>::GetRelativePtOnQuadrilatere(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *alphaX,double *alphaY)
00461 {
00462 double _alphaX,_alphaY;
00463 if (!alphaX) alphaX=&_alphaX;
00464 if (!alphaY) alphaY=&_alphaY;
00465
00466
00467 if (!GetRelativePtOn2Lines(a,b,d,c,alphaX)) return FALSE;
00468 if (!GetRelativePtOn2Lines(a,d,b,c,alphaY)) return FALSE;
00469 return TRUE;
00470 }
00471
00472 template <class T>
00473 BOOL Point2D<T>::GetRelativePtOn2Lines(Point2D<T> &a,Point2D<T> &b,Point2D<T> &c,Point2D<T> &d,double *alpha)
00474 {
00475 double _alpha;
00476 if (!alpha) alpha=&_alpha;
00477
00478
00479 double _a,_b,_c;
00480 _a =
00481 (a.y-b.y)*(d.x-c.x)
00482 -(a.x-b.x)*(d.y-c.y);
00483 _b =
00484 (a.y-b.y)*(c.x-a.x)
00485 -(a.x-b.x)*(c.y-a.y)
00486 +(a.x-b.x-c.x+d.x)*(y-a.y)
00487 -(a.y-b.y-c.y+d.y)*(x-a.x);
00488 _c =
00489 (y-a.y)*(c.x-a.x)
00490 -(x-a.x)*(c.y-a.y);
00491
00492
00493 if (!_a)
00494 {
00495 if (!_b) return FALSE;
00496 *alpha=-_c/_b;
00497 }
00498 else
00499 {
00500
00501
00502 double delta=_b*_b-4.0*_a*_c;
00503 if (delta<0) return FALSE;
00504 double alpha1,alpha2;
00505 double sqrtdelta = sqrt(delta);
00506 alpha1 = (-_b-sqrtdelta)/(2.0*_a);
00507 alpha2 = (-_b+sqrtdelta)/(2.0*_a);
00508
00509 if (fabs(alpha1)<fabs(alpha2)) *alpha=alpha1;
00510 else *alpha=alpha2;
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 }
00525 return TRUE;
00526 }
00527
00528
00529
00530
00531 template <class T>
00532 Point3D<T> Point3D<T>::QuaternionRotate (Point3D<T> &rotate)
00533 {
00534 return *this;
00535 Quaternion qbase,qrotate;
00536
00537 qbase.from_euler(*this);
00538 qrotate.from_euler(rotate);
00539 qbase*=qrotate;
00540 return qbase.to_euler();
00541 }
00542
00543 template <class T>
00544 BOOL Point3D<T>::IsOnTriangle(Point3D<T> &a,Point3D<T> &b,Point3D<T> &c)
00545 {
00546 Point2D<T> _p,_a,_b,_c,_pp;
00547 double alphaBC,alphaAPP;
00548 _p=this;
00549 _a=a;
00550 _b=b;
00551 _c=c;
00552 if (!_p.IsOnTriangle(_a,_b,_c,&alphaBC,&alphaAPP,&_pp)) return FALSE;
00553 Point3D pp;
00554 pp=_pp;
00555 pp.z.LinearInterpolation(b.z,c.z,alphaBC);
00556 z.LinearInterpolation(a.z,pp.z,alphaAPP);
00557 return TRUE;
00558 }
00559
00560 template <class T>
00561 void Point3D<T>::operator= (Point2D<T> &src)
00562 {
00563 x=src.x;
00564 y=src.y;
00565 z=0;
00566 }
00567
00568 template <class T>
00569 void Point3D<T>::operator=(Point3D<T> &src)
00570 {
00571 x=src.x;
00572 y=src.y;
00573 z=src.z;
00574 }
00575
00576 template <class T>
00577 void Point3D<T>::Add(T _x,T _y,T _z)
00578 {
00579 x+=_x;
00580 y+=_y;
00581 z+=_z;
00582 }
00583
00584 template <class T>
00585 void Point3D<T>::operator+=(Point3D<T> &src)
00586 {
00587 x+=src.x;
00588 y+=src.y;
00589 z+=src.z;
00590 }
00591
00592 template <class T>
00593 void Point3D<T>::operator/=(double divide)
00594 {
00595 x/=divide;
00596 y/=divide;
00597 z/=divide;
00598 }
00599
00600 template <class T>
00601 void Point3D<T>::glRotated(double ratio)
00602 {
00603 if (!ratio) return;
00604 if (ratio==1) glRotated();
00605 else
00606 {
00607 if (x) ::glRotated(x*ratio,1,0,0);
00608 if (y) ::glRotated(y*ratio,0,1,0);
00609 if (z) ::glRotated(z*ratio,0,0,1);
00610 }
00611 }
00612
00613 template <class T>
00614 void Point3D<T>::glRotated()
00615 {
00616 if (x) ::glRotated(x,1,0,0);
00617 if (y) ::glRotated(y,0,1,0);
00618 if (z) ::glRotated(z,0,0,1);
00619 }
00620
00621 template <class T>
00622 void Point3D<T>::glTranslated(double ratio)
00623 {
00624 if (!ratio) return;
00625 if (x||y||z) ::glTranslated(x*ratio,y*ratio,z*ratio);
00626 }
00627
00628 template <class T>
00629 void Point3D<T>::glTranslated()
00630 {
00631 if (x||y||z) ::glTranslated(x,y,z);
00632 }
00633
00634 #endif