00001
00002
00003
00004
00005
00006
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; }
00039 inline int isinf(float v){ return 0; }
00040 #endif
00041
00043
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
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
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
00087 #ifdef ADSO_WINDOWS
00088
00089
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
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
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
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
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
00345 class p3f {
00346 public:
00347 float t,p,r;
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
00378 class s2f {
00379 public:
00380 float t,p;
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
00412 class s2d {
00413 public:
00414 double t,p;
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
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
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
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
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
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
00724 class tri3n {
00725 public:
00726 v3f v0, v1, v2;
00727 v3f n0, n1, n2;
00728
00729 tri3n(){}
00730 };
00731
00732
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
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
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
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
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
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