2 #ifndef _QUATERNIONS_H_
3 #define _QUATERNIONS_H_
11 #include "PhysicsMath.h"
14 /**> Quaternion Structures <**/
15 #define PI 3.14159265355555897932384626
18 #define deg2rad .0174532925
20 //using namespace std;
21 typedef float Matrix_t [4][4];
40 inline XYZ operator+(XYZ add);
41 inline XYZ operator-(XYZ add);
42 inline XYZ operator*(float add);
43 inline XYZ operator*(XYZ add);
44 inline XYZ operator/(float add);
45 inline void operator+=(XYZ add);
46 inline void operator-=(XYZ add);
47 inline void operator*=(float add);
48 inline void operator*=(XYZ add);
49 inline void operator/=(float add);
50 inline void operator=(float add);
51 inline void vec(Vector add);
52 inline bool operator==(XYZ add);
55 /*********************> Quaternion Function definition <********/
56 quaternion To_Quat(int Degree_Flag, euler Euler);
57 quaternion To_Quat(angle_axis Ang_Ax);
58 quaternion To_Quat(Matrix_t m);
59 angle_axis Quat_2_AA(quaternion Quat);
60 void Quat_2_Matrix(quaternion Quat, Matrix_t m);
61 quaternion Normalize(quaternion Quat);
62 quaternion Quat_Mult(quaternion q1, quaternion q2);
63 quaternion QNormalize(quaternion Quat);
64 XYZ Quat2Vector(quaternion Quat);
66 inline void CrossProduct(XYZ *P, XYZ *Q, XYZ *V);
67 inline void CrossProduct(XYZ P, XYZ Q, XYZ *V);
68 inline void Normalise(XYZ *vectory);
69 inline float normaldotproduct(XYZ point1, XYZ point2);
70 inline float fast_sqrt (register float arg);
71 bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3);
72 bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p);
73 float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p);
74 float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ n, XYZ *p);
75 float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc,XYZ *n, XYZ *p);
76 float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc, XYZ *p);
77 bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33);
78 bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p);
79 inline void ReflectVector(XYZ *vel, XYZ *n);
80 inline XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang);
81 inline XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang);
82 inline float findDistance(XYZ *point1, XYZ *point2);
83 inline float findLength(XYZ *point1);
84 inline float findLengthfast(XYZ *point1);
85 inline float findDistancefast(XYZ *point1, XYZ *point2);
86 inline float findDistancefast(XYZ point1, XYZ point2);
87 inline float findDistancefastflat(XYZ *point1, XYZ *point2);
88 inline float dotproduct(XYZ *point1, XYZ *point2);
89 bool sphere_line_intersection (
90 float x1, float y1 , float z1,
91 float x2, float y2 , float z2,
92 float x3, float y3 , float z3, float r );
93 bool sphere_line_intersection (
94 XYZ *p1, XYZ *p2, XYZ *p3, float *r );
95 inline bool DistancePointLine( XYZ *Point, XYZ *LineStart, XYZ *LineEnd, float *Distance, XYZ *Intersection );
98 inline void Normalise(XYZ *vectory) {
100 d = fast_sqrt(vectory->x*vectory->x+vectory->y*vectory->y+vectory->z*vectory->z);
107 inline XYZ XYZ::operator+(XYZ add){
116 inline XYZ XYZ::operator-(XYZ add){
125 inline XYZ XYZ::operator*(float add){
133 inline XYZ XYZ::operator*(XYZ add){
141 inline XYZ XYZ::operator/(float add){
149 inline void XYZ::operator+=(XYZ add){
155 inline void XYZ::operator-=(XYZ add){
161 inline void XYZ::operator*=(float add){
167 inline void XYZ::operator*=(XYZ add){
173 inline void XYZ::operator/=(float add){
179 inline void XYZ::operator=(float add){
185 inline void XYZ::vec(Vector add){
191 inline bool XYZ::operator==(XYZ add){
192 if(x==add.x&&y==add.y&&z==add.z)return 1;
196 inline void CrossProduct(XYZ *P, XYZ *Q, XYZ *V){
197 V->x = P->y * Q->z - P->z * Q->y;
198 V->y = P->z * Q->x - P->x * Q->z;
199 V->z = P->x * Q->y - P->y * Q->x;
202 inline void CrossProduct(XYZ P, XYZ Q, XYZ *V){
203 V->x = P.y * Q.z - P.z * Q.y;
204 V->y = P.z * Q.x - P.x * Q.z;
205 V->z = P.x * Q.y - P.y * Q.x;
208 inline float fast_sqrt (register float arg)
211 // Can replace with slower return std::sqrt(arg);
212 register float result;
214 if (arg == 0.0) return 0.0;
217 frsqrte result,arg // Calculate Square root
220 // Newton Rhapson iterations.
221 result = result + 0.5 * result * (1.0 - arg * result * result);
222 result = result + 0.5 * result * (1.0 - arg * result * result);
230 inline float normaldotproduct(XYZ point1, XYZ point2){
231 static GLfloat returnvalue;
234 returnvalue=(point1.x*point2.x+point1.y*point2.y+point1.z*point2.z);
238 inline void ReflectVector(XYZ *vel, XYZ *n)
242 static float dotprod;
244 dotprod=dotproduct(n,vel);
253 vel->x = vt.x - vn.x;
254 vel->y = vt.y - vn.y;
255 vel->z = vt.z - vn.z;
258 inline float dotproduct(XYZ *point1, XYZ *point2){
259 static GLfloat returnvalue;
260 returnvalue=(point1->x*point2->x+point1->y*point2->y+point1->z*point2->z);
264 inline float findDistance(XYZ *point1, XYZ *point2){
265 return(fast_sqrt((point1->x-point2->x)*(point1->x-point2->x)+(point1->y-point2->y)*(point1->y-point2->y)+(point1->z-point2->z)*(point1->z-point2->z)));
268 inline float findLength(XYZ *point1){
269 return(fast_sqrt((point1->x)*(point1->x)+(point1->y)*(point1->y)+(point1->z)*(point1->z)));
273 inline float findLengthfast(XYZ *point1){
274 return((point1->x)*(point1->x)+(point1->y)*(point1->y)+(point1->z)*(point1->z));
277 inline float findDistancefast(XYZ *point1, XYZ *point2){
278 return((point1->x-point2->x)*(point1->x-point2->x)+(point1->y-point2->y)*(point1->y-point2->y)+(point1->z-point2->z)*(point1->z-point2->z));
281 inline float findDistancefast(XYZ point1, XYZ point2){
282 return((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z));
285 inline float findDistancefastflat(XYZ *point1, XYZ *point2){
286 return((point1->x-point2->x)*(point1->x-point2->x)+(point1->z-point2->z)*(point1->z-point2->z));
289 inline XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang){
306 newpoint.z=thePoint.z*cosf(yang)-thePoint.x*sinf(yang);
307 newpoint.x=thePoint.z*sinf(yang)+thePoint.x*cosf(yang);
308 thePoint.z=newpoint.z;
309 thePoint.x=newpoint.x;
313 newpoint.x=thePoint.x*cosf(zang)-thePoint.y*sinf(zang);
314 newpoint.y=thePoint.y*cosf(zang)+thePoint.x*sinf(zang);
315 thePoint.x=newpoint.x;
316 thePoint.y=newpoint.y;
320 newpoint.y=thePoint.y*cosf(xang)-thePoint.z*sinf(xang);
321 newpoint.z=thePoint.y*sinf(xang)+thePoint.z*cosf(xang);
322 thePoint.z=newpoint.z;
323 thePoint.y=newpoint.y;
329 inline float square( float f ) { return (f*f) ;}
331 inline bool sphere_line_intersection (
332 float x1, float y1 , float z1,
333 float x2, float y2 , float z2,
334 float x3, float y3 , float z3, float r )
337 // x1,y1,z1 P1 coordinates (point of line)
338 // x2,y2,z2 P2 coordinates (point of line)
339 // x3,y3,z3, r P3 coordinates and radius (sphere)
340 // x,y,z intersection coordinates
342 // This function returns a pointer array which first index indicates
343 // the number of intersection point, followed by coordinate pairs.
345 static float x , y , z;
346 static float a, b, c, mu, i ;
348 if(x1>x3+r&&x2>x3+r)return(0);
349 if(x1<x3-r&&x2<x3-r)return(0);
350 if(y1>y3+r&&y2>y3+r)return(0);
351 if(y1<y3-r&&y2<y3-r)return(0);
352 if(z1>z3+r&&z2>z3+r)return(0);
353 if(z1<z3-r&&z2<z3-r)return(0);
354 a = square(x2 - x1) + square(y2 - y1) + square(z2 - z1);
355 b = 2* ( (x2 - x1)*(x1 - x3)
356 + (y2 - y1)*(y1 - y3)
357 + (z2 - z1)*(z1 - z3) ) ;
358 c = square(x3) + square(y3) +
359 square(z3) + square(x1) +
360 square(y1) + square(z1) -
361 2* ( x3*x1 + y3*y1 + z3*z1 ) - square(r) ;
362 i = b * b - 4 * a * c ;
372 inline bool sphere_line_intersection (
373 XYZ *p1, XYZ *p2, XYZ *p3, float *r )
376 // x1,p1->y,p1->z P1 coordinates (point of line)
377 // p2->x,p2->y,p2->z P2 coordinates (point of line)
378 // p3->x,p3->y,p3->z, r P3 coordinates and radius (sphere)
379 // x,y,z intersection coordinates
381 // This function returns a pointer array which first index indicates
382 // the number of intersection point, followed by coordinate pairs.
384 static float x , y , z;
385 static float a, b, c, mu, i ;
387 if(p1->x>p3->x+*r&&p2->x>p3->x+*r)return(0);
388 if(p1->x<p3->x-*r&&p2->x<p3->x-*r)return(0);
389 if(p1->y>p3->y+*r&&p2->y>p3->y+*r)return(0);
390 if(p1->y<p3->y-*r&&p2->y<p3->y-*r)return(0);
391 if(p1->z>p3->z+*r&&p2->z>p3->z+*r)return(0);
392 if(p1->z<p3->z-*r&&p2->z<p3->z-*r)return(0);
393 a = square(p2->x - p1->x) + square(p2->y - p1->y) + square(p2->z - p1->z);
394 b = 2* ( (p2->x - p1->x)*(p1->x - p3->x)
395 + (p2->y - p1->y)*(p1->y - p3->y)
396 + (p2->z - p1->z)*(p1->z - p3->z) ) ;
397 c = square(p3->x) + square(p3->y) +
398 square(p3->z) + square(p1->x) +
399 square(p1->y) + square(p1->z) -
400 2* ( p3->x*p1->x + p3->y*p1->y + p3->z*p1->z ) - square(*r) ;
401 i = b * b - 4 * a * c ;
411 inline XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang){
418 newpoint.z=oldpoint.z*cosf(yang)-oldpoint.x*sinf(yang);
419 newpoint.x=oldpoint.z*sinf(yang)+oldpoint.x*cosf(yang);
420 oldpoint.z=newpoint.z;
421 oldpoint.x=newpoint.x;
425 newpoint.x=oldpoint.x*cosf(zang)-oldpoint.y*sinf(zang);
426 newpoint.y=oldpoint.y*cosf(zang)+oldpoint.x*sinf(zang);
427 oldpoint.x=newpoint.x;
428 oldpoint.y=newpoint.y;
432 newpoint.y=oldpoint.y*cosf(xang)-oldpoint.z*sinf(xang);
433 newpoint.z=oldpoint.y*sinf(xang)+oldpoint.z*cosf(xang);
434 oldpoint.z=newpoint.z;
435 oldpoint.y=newpoint.y;
442 inline bool DistancePointLine( XYZ *Point, XYZ *LineStart, XYZ *LineEnd, float *Distance, XYZ *Intersection )
447 LineMag = findDistance( LineEnd, LineStart );
449 U = ( ( ( Point->x - LineStart->x ) * ( LineEnd->x - LineStart->x ) ) +
450 ( ( Point->y - LineStart->y ) * ( LineEnd->y - LineStart->y ) ) +
451 ( ( Point->z - LineStart->z ) * ( LineEnd->z - LineStart->z ) ) ) /
452 ( LineMag * LineMag );
454 if( U < 0.0f || U > 1.0f )
455 return 0; // closest point does not fall within the line segment
457 Intersection->x = LineStart->x + U * ( LineEnd->x - LineStart->x );
458 Intersection->y = LineStart->y + U * ( LineEnd->y - LineStart->y );
459 Intersection->z = LineStart->z + U * ( LineEnd->z - LineStart->z );
461 *Distance = findDistance( Point, Intersection );