Main Page | Modules | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

adsomath.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * $Id: adsomath.h,v 1.16 2003/06/27 08:36:41 schou Exp $
00003  * Author: Jakob Schou Jensen <schou@sourceforge.net>
00004  * Licence: GPL
00005  *
00006  * Description: Adso math
00007  *
00008  ****************************************************************************/
00009 
00012 
00013 #ifndef ADSOMATH_H
00014 #define ADSOMATH_H
00015 
00016 #include <stdlib.h>
00017 #include <math.h>
00018 #include <adsobase.h>
00019 
00020 #ifdef ADSO_WINDOWS
00021 #define M_PI    3.14159265358979323846
00022 #define M_TWOPI         (M_PI * 2.0)
00023 #define M_PI_2    1.57079632679489661923
00024 #define M_PI_4    0.78539816339744830962
00025 #define M_3PI_4   2.3561944901923448370E0
00026 inline float sin(float v){ return (float)sin((double)v); }
00027 inline float cos(float v){ return (float)cos((double)v); }
00028 inline float tan(float v){ return (float)tan((double)v); }
00029 inline float asin(float v){ return (float)asin((double)v); }
00030 inline float acos(float v){ return (float)acos((double)v); }
00031 inline float atan(float v){ return (float)atan((double)v); }
00032 inline float sqrt(float v){ return (float)sqrt((double)v); }
00033 inline float floor(float v){ return (float)floor((double)v); }
00034 inline float ceil(float v){ return (float)ceil((double)v); }
00035 inline float fabs(float v){ return (float)fabs((double)v); }
00036 inline float hypot(float a1, float a2){ return (float)hypot((double)a1,(double)a2); }
00037 inline float pow(float a1, float a2){ return (float)pow((double)a1,(double)a2); }
00038 inline int isnan(float v){ return 0; } // XXX fix this
00039 inline int isinf(float v){ return 0; } // XXX fix this
00040 #endif
00041 
00043 // Basic math
00045 inline double sqr(double v){return v*v;}
00046 inline double cub(double v){return v*v*v;}
00047 inline float sqr(float v){return v*v;}
00048 inline float cub(float v){return v*v*v;}
00049 
00050 // Clamp to [-1,1]
00051 inline float clamp(float v){
00052   if(v<-1.0) return -1.0;
00053   else if(v>1.0) return 1.0;
00054   return v;
00055 }
00056 
00057 inline double clamp(double v){
00058   if(v<-1.0) return -1.0;
00059   else if(v>1.0) return 1.0;
00060   return v;
00061 }
00062 
00063 // PI normalize [-PI,PI]
00064 inline float pin(float v){
00065   while(v>M_PI) v-=(float)M_PI*2.0f;
00066   while(v<-M_PI) v+=(float)M_PI*2.0f;
00067   return v;
00068 }
00069 
00070 inline double pin(double v){
00071   while(v>M_PI) v-=M_PI*2.0;
00072   while(v<-M_PI) v+=M_PI*2.0;
00073   return v;
00074 }
00075 
00076 inline float sign(float v){
00077   if(v<0.0) return -1.0;
00078   else return 1.0;
00079 }
00080 
00081 inline double sign(double v){
00082   if(v<0.0) return -1.0;
00083   else return 1.0;
00084 }
00085 
00086 // frandom(mag) : returns a random value in the intervaæ ]mag:0]
00087 #ifdef ADSO_WINDOWS
00088 //inline unsigned int random(){ return (unsigned int)rand() * (unsigned int)rand(); }
00089 //inline void srandom(unsigned int seed){ srand(seed); }
00090 unsigned int random();
00091 void srandom(unsigned int seed);
00092 double frandom(double mag);
00093 inline float frandom(float mag){ return (float)frandom((double)mag); }
00094 #else
00095 inline double frandom(double mag){
00096   return (double)random()/(double)RAND_MAX*mag;
00097 }
00098 #endif
00099 
00100 
00102 // Vector 2D double
00104 class v2d {
00105 public:
00106   double x,y;
00107 
00108   v2d hat(){
00109     return v2d(-y,x);
00110   }
00111 
00112   double length(){
00113     return hypot(x,y);
00114   }
00115 
00116   double dist(v2d p){
00117     return hypot(x-p.x,y-p.y);
00118   }
00119 
00120   v2d norm(){
00121     double l=hypot(x,y);
00122     return v2d(x/l,y/l);
00123   }
00124 
00125   v2d operator=(const v2d v){
00126     x = v.x;
00127     y = v.y;
00128     return v2d(x,y);
00129   }
00130 
00131   int operator==(const v2d a){
00132     return x==a.x && y==a.y;
00133   }
00134 
00135   v2d operator+(const v2d a){
00136     return v2d(x+a.x,y+a.y);
00137   }
00138 
00139   v2d operator-(const v2d a){
00140     return v2d(x-a.x,y-a.y);
00141   }
00142 
00143   v2d operator*(const v2d a){
00144     return v2d(x*a.x,y*a.y);
00145   }
00146 
00147   v2d operator/(const double d){
00148     return v2d(x/d,y/d);
00149   }
00150 
00151   v2d operator*(const double m){
00152     return v2d(x*m,y*m);
00153   }
00154 
00155   friend v2d operator*(const double m,v2d v){
00156     return v2d(v.x*m,v.y*m);
00157   }
00158 
00159   v2d(double cx, double cy){
00160     x=cx;
00161     y=cy;
00162   }
00163 
00164   v2d(){
00165     x=0; y=0;
00166   }
00167 };
00168 
00169 inline double det(v2d a, v2d b){
00170   return a.x*b.y-a.y*b.x;
00171 }
00172 
00174 // Vector 2D float
00176 class v2f {
00177 public:
00178   float x,y;
00179 
00180   v2f hat(){
00181     return v2f(-y,x);
00182   }
00183 
00184   float length(){
00185     return (float)hypot(x,y);
00186   }
00187 
00188   float dist(v2f p){
00189     return (float)hypot(x-p.x,y-p.y);
00190   }
00191 
00192   v2f norm(){
00193     float l = (float)hypot(x,y);
00194     return v2f(x/l,y/l);
00195   }
00196 
00197   v2f operator=(const v2f v){
00198     x = v.x;
00199     y = v.y;
00200     return v2f(x,y);
00201   }
00202 
00203   int operator==(const v2f a){
00204     return x==a.x && y==a.y;
00205   }
00206 
00207   v2f operator+(const v2f a){
00208     return v2f(x+a.x,y+a.y);
00209   }
00210 
00211   v2f operator-(const v2f a){
00212     return v2f(x-a.x,y-a.y);
00213   }
00214 
00215   v2f operator*(const v2f a){
00216     return v2f(x*a.x,y*a.y);
00217   }
00218 
00219   v2f operator/(const float d){
00220     return v2f(x/d,y/d);
00221   }
00222 
00223   v2f operator*(const float m){
00224     return v2f(x*m,y*m);
00225   }
00226 
00227   friend v2f operator*(const float m,v2f v){
00228     return v2f(v.x*m,v.y*m);
00229   }
00230 
00231   v2f(float cx, float cy){
00232     x=cx;
00233     y=cy;
00234   }
00235 
00236   v2f::v2f(class p3f p);
00237 
00238   v2f(){
00239     x=0; y=0;
00240   }
00241 };
00242 
00243 inline float det(v2f a, v2f b){
00244   return a.x*b.y-a.y*b.x;
00245 }
00246 
00248 // Vector 3D float
00250 class v3f {
00251 public:
00252   float x,y,z;
00253 
00254   float length(){
00255     return (float)sqrt(x*x+y*y+z*z);
00256   }
00257 
00258   float dist(v3f p){
00259     return (float)sqrt(((x-p.x)*(x-p.x))+((y-p.y)*(y-p.y))+((z-p.z)*(z-p.z)));
00260   }
00261 
00262   v3f norm(){
00263     float l = sqrt(x*x+y*y+z*z);
00264     //if(l<1e-20&&0) return v3f(1.0,0.0,0.0);
00265     return v3f(x/l,y/l,z/l);
00266   }
00267 
00268   v3f operator=(const v3f v){
00269     x = v.x;
00270     y = v.y;
00271     z = v.z;
00272     return v3f(x,y,z);
00273   }
00274 
00275   int operator==(const v3f a){
00276     return x==a.x && y==a.y && z==a.z;
00277   }
00278 
00279   v3f operator+(const v3f a){
00280     return v3f(x+a.x,y+a.y,z+a.z);
00281   }
00282 
00283   v3f operator-(const v3f a){
00284     return v3f(x-a.x,y-a.y,z-a.z);
00285   }
00286 
00287   v3f operator/(const float d){
00288     return v3f(x/d,y/d,z/d);
00289   }
00290 
00291   float operator*(const v3f v){
00292     return x*v.x + y*v.y + z*v.z;
00293   }
00294 
00295   v3f operator*(const float m){
00296     return v3f(x*m,y*m,z*m);
00297   }
00298 
00299   friend v3f operator*(const float m,const v3f v){
00300     return v3f(v.x*m,v.y*m,v.z*m);
00301   }
00302 
00303   v3f operator-(){
00304     return v3f(-x,-y,-z);
00305   }
00306 
00307   v3f operator-=(const v3f a){
00308     x = x-a.x;
00309     y = y-a.y;
00310     z = z-a.z;
00311     return v3f(x,y,z);
00312   }
00313 
00314   v3f operator+=(const v3f a){
00315     x = x+a.x;
00316     y = y+a.y;
00317     z = z+a.z;
00318     return v3f(x,y,z);
00319   }
00320 
00321   v3f(float cx, float cy, float cz){
00322     x=cx;
00323     y=cy;
00324     z=cz;
00325   }
00326 
00327   v3f(class p3f p);
00328   v3f(class s2f p);
00329   v3f(class s2d p);
00330 
00331   v3f(){
00332     x=0; y=0; z=0;
00333   }
00334 };
00335 
00336 inline v3f cross(v3f a, v3f b){
00337   return v3f(a.y*b.z-a.z*b.y, 
00338        a.z*b.x-a.x*b.z, 
00339        a.x*b.y-a.y*b.x);
00340 }
00341 
00343 // Polar vector 3D float
00345 class p3f {
00346 public:
00347   float t,p,r; // theta, phi, radius (lenght)
00348 
00349   p3f operator*(const float m){
00350     return p3f(t,p,r*m);
00351   }
00352 
00353   float sphereDist(p3f q){
00354     return (float)(acos(cos(t)*cos(q.t)+sin(t)*sin(q.t)*cos(q.p-p)));
00355   }
00356 
00357   p3f(float ct, float cp, float cr){
00358     p=cp;
00359     t=ct;
00360     r=cr;
00361   }
00362 
00363   p3f(){
00364     p=0; t=0; r=0;
00365   }
00366 };
00367 
00368 
00369 inline v3f::v3f(p3f p){
00370   x = (float)(sin(p.t)*cos(p.p)*p.r);
00371   y = (float)(sin(p.t)*sin(p.p)*p.r);
00372   z = (float)(cos(p.t)*p.r);
00373 }
00374 
00376 // Sphere vector Float
00378 class s2f {
00379 public:
00380   float t,p; // theta, phi, radius (lenght)
00381 
00382   s2f(float ct, float cp){
00383     p=cp;
00384     t=ct;
00385   }
00386 
00387   s2f(){
00388     p=0; t=0;
00389   }
00390 
00391   s2f(const p3f v){
00392     t = v.t;
00393     p = v.p;
00394   }
00395 
00396   s2f(const v3f v){
00397     v3f n = v;
00398     float s;
00399 
00400     n = n.norm();
00401     s = (float)sqrt(1.0-sqr(n.z));
00402 
00403     t = (float)acos(n.z);
00404     if(s<1e-10) p = 0;
00405     else p = (float)acos(clamp(n.x/s))*sign(n.y);
00406   }
00407 };
00408 
00410 // Sphere vector Double
00412 class s2d {
00413 public:
00414   double t,p; // theta, phi, radius (lenght)
00415 
00416   s2d zy_rotate(double at, double ap){
00417     double cz,sac_cz,cx;
00418 
00419     cz = clamp((float)(cos(at)*cos(t)-sin(at)*sin(t)*cos(ap+p)));
00420     sac_cz = sqrt(1.0-sqr(cz));
00421     cx = sin(at)*cos(t)+cos(at)*sin(t)*cos(ap+p);
00422 
00423     if(sac_cz>1e-10)
00424       return s2d(acos(cz), acos(clamp(cx/sac_cz))*sign(pin(ap+p)));
00425     else
00426       return s2d(acos(cz), 0.0);
00427   }
00428 
00429   s2d yz_rotate(double at, double ap){
00430     double cz,sac_cz,cx;
00431 
00432     cz = clamp(cos(at)*cos(t)-sin(at)*sin(t)*cos(p));
00433     sac_cz = sqrt(1.0-sqr(cz));
00434     cx = sin(at)*cos(t)+cos(at)*sin(t)*cos(p);
00435 
00436     if(sac_cz>1e-10)
00437       return s2d(acos(cz), pin(acos(clamp(cx/sac_cz))*sign(pin(p))+ap));
00438     else
00439       return s2d(acos(cz), 0.0);
00440   }
00441 
00442   double sphereDist(s2d q){
00443     return acos(cos(t)*cos(q.t)+sin(t)*sin(q.t)*cos(q.p-p));
00444   }
00445 
00446   double sphereDist_dt(s2d q){
00447     double d = sqrt(1.0-sqr(cos(t)*cos(q.t)+sin(t)*sin(q.t)*cos(q.p-p)));
00448     if(d<1e-10) return 0.0;
00449     else return (cos(t)*sin(q.t)-sin(t)*cos(q.t)*cos(p-q.p))/d;
00450   }
00451 
00452   double sphereDist_dp(s2d q){
00453     double d = sqrt(1.0-sqr(cos(t)*cos(q.t)+sin(t)*sin(q.t)*cos(q.p-p)));
00454     if(d<1e-10) return 0.0;
00455     else return (sin(t)*sin(q.t)*sin(q.p-p))/d;
00456   }
00457 
00458   s2d(double ct, double cp){
00459     p=cp;
00460     t=ct;
00461   }
00462 
00463   s2d(){
00464     p=0; t=0;
00465   }
00466 };
00467 
00468 inline v3f::v3f(s2f p){
00469   x = (float)(sin(p.t)*cos(p.p));
00470   y = (float)(sin(p.t)*sin(p.p));
00471   z = (float)cos(p.t);
00472 }
00473 
00474 inline v3f::v3f(s2d p){
00475   x = (float)(sin(p.t)*cos(p.p));
00476   y = (float)(sin(p.t)*sin(p.p));
00477   z = (float)cos(p.t);
00478 }
00479 
00480 // used by some pseudo realistic texture coord generator
00481 inline v2f::v2f(p3f p){
00482   x = (float)(sin(p.t)*cos(p.p));
00483   y = (float)(sin(p.t)*sin(p.p));
00484 }
00485 
00487 // Square Matrix 3x3 Float
00489 class sqm3f {
00490  public:
00491   float m[3][3];
00492 
00493   v3f col(int i){
00494     return v3f(m[0][i],m[1][i],m[2][i]);
00495   }
00496 
00497   v3f row(int i){
00498     return v3f(m[i][0],m[i][1],m[i][2]);
00499   }
00500 
00501   void setcol(int i, v3f c){
00502     m[0][i] = c.x; m[1][i] = c.y; m[2][i] = c.z;
00503   }
00504 
00505   void setrow(int i, v3f c){
00506     m[i][0] = c.x; m[i][1] = c.y; m[i][2] = c.z;
00507   }
00508 
00509   sqm3f operator=(const sqm3f v){
00510     m[0][0] = v.m[0][0];  m[0][1] = v.m[0][1];  m[0][2] = v.m[0][2];
00511     m[1][0] = v.m[1][0];  m[1][1] = v.m[1][1];  m[1][2] = v.m[1][2];
00512     m[2][0] = v.m[2][0];  m[2][1] = v.m[2][1];  m[2][2] = v.m[2][2];
00513     return sqm3f(m);
00514   }
00515 
00516   sqm3f operator+=(const sqm3f a){
00517     m[0][0] += a.m[0][0];  m[0][1] += a.m[0][1];  m[0][2] += a.m[0][2];
00518     m[1][0] += a.m[1][0];  m[1][1] += a.m[1][1];  m[1][2] += a.m[1][2];
00519     m[2][0] += a.m[2][0];  m[2][1] += a.m[2][1];  m[2][2] += a.m[2][2];
00520     return sqm3f(m);
00521   }
00522 
00523   sqm3f operator+(const sqm3f a){
00524     sqm3f r;
00525     r.m[0][0] = m[0][0] + a.m[0][0];  r.m[0][1] = m[0][1] + a.m[0][1];  r.m[0][2] = m[0][2] + a.m[0][2];
00526     r.m[1][0] = m[1][0] + a.m[1][0];  r.m[1][1] = m[1][1] + a.m[1][1];  r.m[1][2] = m[1][2] + a.m[1][2];
00527     r.m[2][0] = m[2][0] + a.m[2][0];  r.m[2][1] = m[2][1] + a.m[2][1];  r.m[2][2] = m[2][2] + a.m[2][2];
00528     return r;
00529   }
00530 
00531   sqm3f operator-=(const sqm3f a){
00532     m[0][0] -= a.m[0][0];  m[0][1] -= a.m[0][1];  m[0][2] -= a.m[0][2];
00533     m[1][0] -= a.m[1][0];  m[1][1] -= a.m[1][1];  m[1][2] -= a.m[1][2];
00534     m[2][0] -= a.m[2][0];  m[2][1] -= a.m[2][1];  m[2][2] -= a.m[2][2];
00535     return sqm3f(m);
00536   }
00537 
00538   sqm3f operator-(const sqm3f a){
00539     sqm3f r;
00540     r.m[0][0] = m[0][0] - a.m[0][0];  r.m[0][1] = m[0][1] - a.m[0][1];  r.m[0][2] = m[0][2] - a.m[0][2];
00541     r.m[1][0] = m[1][0] - a.m[1][0];  r.m[1][1] = m[1][1] - a.m[1][1];  r.m[1][2] = m[1][2] - a.m[1][2];
00542     r.m[2][0] = m[2][0] - a.m[2][0];  r.m[2][1] = m[2][1] - a.m[2][1];  r.m[2][2] = m[2][2] - a.m[2][2];
00543     return r;
00544   }
00545 
00546   sqm3f operator*(const sqm3f a){
00547     sqm3f r;
00548     int i,j;
00549     for(j=0;j<3;j++){
00550       for(i=0;i<3;i++){
00551   r.m[i][j] = m[i][0]*a.m[0][j] + m[i][1]*a.m[1][j] + m[i][2]*a.m[2][j];
00552       }
00553     }
00554     return r;
00555   }
00556 
00557   int operator==(const sqm3f a){
00558     int i,j;
00559     for(j=0;j<3;j++){
00560       for(i=0;i<3;i++){
00561   if(a.m[i][j] != m[i][j]) return 0;
00562       }
00563     }
00564     return 1;
00565   }
00566 
00567   v3f operator*(const v3f v){
00568     return v3f(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z,
00569          m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z,
00570          m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z);
00571   }
00572 
00573   sqm3f operator*(const float f){
00574     sqm3f p;
00575     p.m[0][0] = m[0][0] * f;  p.m[0][1] = m[0][1] * f;  p.m[0][2] = m[0][2] * f;
00576     p.m[1][0] = m[1][0] * f;  p.m[1][1] = m[1][1] * f;  p.m[1][2] = m[1][2] * f;
00577     p.m[2][0] = m[2][0] * f;  p.m[2][1] = m[2][1] * f;  p.m[2][2] = m[2][2] * f;
00578     return p;
00579   }
00580 
00581   sqm3f operator*=(const float f){
00582     m[0][0] *= f;  m[0][1] *= f;  m[0][2] *= f;
00583     m[1][0] *= f;  m[1][1] *= f;  m[1][2] *= f;
00584     m[2][0] *= f;  m[2][1] *= f;  m[2][2] *= f;
00585     return sqm3f(m);
00586   }
00587 
00588   sqm3f trans(){
00589     sqm3f r;
00590     r.m[0][0] = m[0][0];  r.m[0][1] = m[1][0];  r.m[0][2] = m[2][0];
00591     r.m[1][0] = m[0][1];  r.m[1][1] = m[1][1];  r.m[1][2] = m[2][1];
00592     r.m[2][0] = m[0][2];  r.m[2][1] = m[1][2];  r.m[2][2] = m[2][2];    
00593     return r;
00594   }
00595 
00596   sqm3f inverse();
00597 
00598   // Vector square: a*b^T
00599   void vsqr(v3f a, v3f b){
00600     m[0][0] = a.x*b.x;  m[0][1] = a.x*b.y;  m[0][2] = a.x*b.z;
00601     m[1][0] = a.y*b.x;  m[1][1] = a.y*b.y;  m[1][2] = a.y*b.z;
00602     m[2][0] = a.z*b.x;  m[2][1] = a.z*b.y;  m[2][2] = a.z*b.z;
00603   }
00604 
00605   void ident(){
00606     m[0][0] = 1.0;  m[0][1] = 0.0;  m[0][2] = 0.0;
00607     m[1][0] = 0.0;  m[1][1] = 1.0;  m[1][2] = 0.0;
00608     m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 1.0;
00609   }
00610 
00611   void zero(){
00612     m[0][0] = 0.0;  m[0][1] = 0.0;  m[0][2] = 0.0;
00613     m[1][0] = 0.0;  m[1][1] = 0.0;  m[1][2] = 0.0;
00614     m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 0.0;
00615   }
00616 
00617   sqm3f(float a[3][3]){
00618     m[0][0] = a[0][0];  m[0][1] = a[0][1];  m[0][2] = a[0][2];
00619     m[1][0] = a[1][0];  m[1][1] = a[1][1];  m[1][2] = a[1][2];
00620     m[2][0] = a[2][0];  m[2][1] = a[2][1];  m[2][2] = a[2][2];
00621   }
00622 
00623   sqm3f(v3f a, v3f b, v3f c){
00624     m[0][0] = a.x;  m[0][1] = b.x;  m[0][2] = c.x;
00625     m[1][0] = a.y;  m[1][1] = b.y;  m[1][2] = c.y;
00626     m[2][0] = a.z;  m[2][1] = b.z;  m[2][2] = c.z;
00627   }
00628 
00629   sqm3f(){
00630     m[0][0] = 0.0;  m[0][1] = 0.0;  m[0][2] = 0.0;
00631     m[1][0] = 0.0;  m[1][1] = 0.0;  m[1][2] = 0.0;
00632     m[2][0] = 0.0;  m[2][1] = 0.0;  m[2][2] = 0.0;
00633   }
00634 };
00635 
00636 inline sqm3f rotateMatrix(float a, v3f v){
00637   sqm3f U,S,R;
00638 
00639   U.vsqr(v,v);
00640   S.m[0][0] = 0.0; S.m[0][1] = -v.z; S.m[0][2] = v.y;
00641   S.m[1][0] = v.z; S.m[1][1] = 0.0; S.m[1][2] = -v.x;
00642   S.m[2][0] = -v.y; S.m[2][1] = v.x; S.m[2][2] = 0.0;
00643 
00644   R.ident();
00645   R -= U;
00646   R *= (float)cos(a);
00647   R += U;
00648   S *= (float)sin(a);
00649   R += S;
00650   
00651   return R;
00652 }
00653 
00654 // rotate u a around v
00655 inline v3f rotate(float a, v3f v, v3f u){
00656   sqm3f U,S,R;
00657 
00658   U.vsqr(v,v);
00659   S.m[0][0] = 0.0;
00660   S.m[0][1] = -v.z;
00661   S.m[0][2] = v.y;
00662   S.m[1][0] = v.z;
00663   S.m[1][1] = 0.0;
00664   S.m[1][2] = -v.x;
00665   S.m[2][0] = -v.y;
00666   S.m[2][1] = v.x;
00667   S.m[2][2] = 0.0;
00668 
00669   R.ident();
00670   R -= U;
00671   R *= cos(a);
00672   R += U;
00673   S *= sin(a);
00674   R += S;
00675   
00676   return R*u;
00677 }
00678 
00679 inline sqm3f star(v3f v){
00680   sqm3f r;
00681   r.m[0][0] = 0;    r.m[0][1] = -v.z; r.m[0][2] = v.y;
00682   r.m[1][0] = v.z;  r.m[1][1] = 0;    r.m[1][2] = -v.x;
00683   r.m[2][0] = -v.y; r.m[2][1] = v.x;  r.m[2][2] = 0;    
00684   return r;
00685 }
00686 
00687 
00689 
00690 class line2d {
00691 public:
00692   v2d v0, v1;
00693 
00694   int intersect(line2d l);
00695   line2d(){}
00696   line2d(v2d p0, v2d p1){
00697     v0 = p0;
00698     v1 = p1;
00699   }
00700 };
00701 
00702 class tri2d {
00703 public:
00704   v2d v0, v1, v2;
00705 
00706   tri2d(){}
00707   tri2d(v2d p0, v2d p1, v2d p2){
00708     v0 = p0;
00709     v1 = p1;
00710     v2 = p2;
00711   }
00712 };
00713 
00714 // 3D triangle
00715 class tri3f {
00716 public:
00717   v3f v0, v1, v2;
00718 
00719   tri3f(){}
00720   tri3f(v3f a, v3f b, v3f c){ v0=a; v1=b; v2=c;}
00721 };
00722 
00723 // 3D triangle with surface normals
00724 class tri3n {
00725 public:
00726   v3f v0, v1, v2;
00727   v3f n0, n1, n2;
00728 
00729   tri3n(){}
00730 };
00731 
00732 // 3D vector and surface normal
00733 class vn3f {
00734 public:
00735   v3f v;
00736   v3f n;
00737 
00738   vn3f(){}
00739   vn3f(v3f sv, v3f sn){v=sv;n=sn;}
00740 };
00741 
00742 // 3D vector, surface normal, and texture coordinate
00743 class vnt3f {
00744 public:
00745   v3f v;
00746   v3f n;
00747   v2f t;
00748 
00749   vnt3f(){}
00750   vnt3f(v3f sv, v3f sn, v2f st){v=sv;n=sn;t=st;}
00751 };
00752 
00753 // 3D vector, surface normal, and two texture coordinate sets
00754 class vntt3f {
00755 public:
00756   v3f v;
00757   v3f n;
00758   v2f t1,t2;
00759 
00760   vntt3f(){}
00761   vntt3f(v3f sv, v3f sn, v2f st1, v2f st2){ v=sv; n=sn; t1=st1; t2=st2; }
00762 };
00763 
00765 
00766 /* simple set (may contain doubles) */
00767 template<class T>
00768 class Set {
00769   int array_size;
00770   int count;
00771   T *array;
00772 public:
00773   T get(int i){ return array[i]; }
00774 
00775   /*
00776   void add(tri_set *ts){
00777     int i,s = tris+ts->count();
00778     if(s>array_size){
00779       if(array_size*2>s) s = array_size*2;
00780       tri *n = new tri[s];
00781       for(i=0;i<tris;i++){
00782   n[i] = array[i];
00783       }
00784       delete(array);
00785       array = n;
00786       array_size = s;
00787     }
00788     for(i=0;i<ts->count();i++)
00789       array[tris+i] = ts->get(i);
00790     tris += ts->count();
00791   }
00792   */
00793 
00794   void add(T t){
00795     if(count==array_size){
00796       T *n = new T[array_size*2];
00797       int i;
00798       for(i=0;i<array_size;i++){
00799   n[i] = array[i];
00800       }
00801       delete(array);
00802       array = n;
00803       array_size *= 2;
00804     }
00805     array[count++] = t;
00806   }
00807 
00808   int size(){ return count; }
00809 
00810   void clear(){
00811     delete(array);
00812     array=new T[16];
00813     array_size=16;
00814     count=0;
00815   }
00816 
00817   Set(){
00818     array=new T[16];
00819     array_size=16;
00820     count=0;
00821   }
00822 };
00823 
00824 class SphereLine {
00825   p3f a,b,c;
00826 
00827  public:
00828   p3f linePoint(float t){
00829     float x,z,cp;
00830     z = clamp(cos(a.t)*cos(t*c.t)-sin(a.t)*sin(t*c.t)*cos(c.p));
00831     x = sin(a.t)*cos(t*c.t)+cos(a.t)*sin(t*c.t)*cos(c.p);
00832     if(1.0-z<1e-10) cp = 0;
00833     else cp = clamp(x/sqrt(1.0f-sqr(z)));
00834     
00835     return p3f( acos(z), pin(acos(cp)*sign(c.p)+a.p), 1.0 );
00836   }
00837 
00838   void generateLine(Set<p3f> *ps, int count){
00839     int j;
00840     for(j=0;j<count;j++){
00841       p3f lp = linePoint((float)j/(float)(count-1));
00842       ps->add(lp);
00843     }
00844   }
00845 
00846   void generateLine(p3f *pl, int count){
00847     int j;
00848     for(j=0;j<count;j++){
00849       pl[j] = linePoint((float)j/(float)(count-1));
00850     }
00851   }
00852 
00853   void endPoints(p3f la, p3f lb){
00854     float z,x,cp;
00855 
00856     a = la;
00857     b = lb;
00858     
00859     z = clamp(cos(a.t)*cos(b.t) + sin(a.t)*sin(b.t)*cos(a.p-b.p));
00860     c.t = acos(z);
00861 
00862     x = cos(a.t)*sin(b.t)*cos(a.p-b.p) - sin(a.t)*cos(b.t);
00863     if(1.0-z<1e-10) cp = 0.0;
00864     else cp = x/sqrt(1.0f-sqr(z));
00865     c.p = acos(cp) * sign(pin(b.p-a.p));
00866   }
00867 
00868   SphereLine(){}
00869 };
00870 
00872 
00873 #endif
00874 

Generated on Mon Jul 21 10:44:47 2003 for Rover by doxygen 1.3.2