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 #ifndef SuperQuadric_C_DEFINED
00040 #define SuperQuadric_C_DEFINED
00041
00042 #include "GUI/SuperQuadric.H"
00043 #include <math.h>
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046
00047 namespace SuperQuadricFunc
00048 {
00049
00050
00051
00052
00053 float sgnf ( float x ) {
00054 if ( x < 0 )
00055 return -1;
00056 if ( x > 0 )
00057 return 1;
00058 return 0;
00059 }
00060
00061
00062 float absf ( float x ) {
00063 if ( x < 0 )
00064 return -x;
00065 return x;
00066 }
00067
00068
00069
00070
00071
00072
00073 float sqC ( float v, float n ) {
00074 return sgnf((float)cos(v)) * (float)powf(absf((float)cos(v)),n);
00075 }
00076
00077
00078
00079
00080
00081
00082 float sqCT ( float v, float n, float alpha ) {
00083 return alpha + sqC(v,n);
00084 }
00085
00086
00087
00088
00089
00090
00091 float sqS ( float v, float n ) {
00092 return sgnf((float)sin(v)) * (float)powf(absf((float)sin(v)),n);
00093 }
00094
00095
00096 void taper(float *x, float *y, float *z,
00097 float az, float Kx, float Ky)
00098 {
00099
00100 *x = ( (Kx/az) * *z + 1) * *x;
00101 *y = ( (Ky/az) * *z + 1) * *y;
00102
00103 }
00104
00105
00106 }
00107
00108 SuperQuadric::SuperQuadric()
00109 {
00110 itsUseDisplayList = false;
00111 itsUseTexture = false;
00112
00113 its_u_segs = 20;
00114 its_v_segs = 20;
00115 }
00116
00117 SuperQuadric::~SuperQuadric()
00118 {
00119 }
00120
00121
00122
00123 void SuperQuadric::ellipsoid ( float a1, float a2, float a3,
00124 float u, float v, float n, float e,
00125 float *x, float *y, float *z,
00126 float *nx, float *ny, float *nz )
00127 {
00128 *x = a1 * SuperQuadricFunc::sqC (u, n) * SuperQuadricFunc::sqC (v, e);
00129 *y = a2 * SuperQuadricFunc::sqC (u, n) * SuperQuadricFunc::sqS (v, e);
00130 *z = a3 * SuperQuadricFunc::sqS (u, n);
00131
00132
00133
00134 *nx= SuperQuadricFunc::sqC (u, 2 - n) * SuperQuadricFunc::sqC (v, 2 - e) / a1;
00135 *ny= SuperQuadricFunc::sqC (u, 2 - n) * SuperQuadricFunc::sqS (v, 2 - e) / a2;
00136 *nz= SuperQuadricFunc::sqS (u, 2 - n) / a3;
00137 }
00138
00139 void SuperQuadric::toroid ( float a1, float a2, float a3,
00140 float u, float v,
00141 float n, float e, float alpha,
00142 float *x, float *y, float *z, float *nx, float *ny, float *nz )
00143 {
00144 float A1, A2, A3;
00145 A1 = 1 / (a1 + alpha);
00146 A2 = 1 / (a2 + alpha);
00147 A3 = 1 / (a3 + alpha);
00148 *x = A1 * SuperQuadricFunc::sqCT (u, e, alpha) * SuperQuadricFunc::sqC (v, n);
00149 *y = A2 * SuperQuadricFunc::sqCT (u, e, alpha) * SuperQuadricFunc::sqS (v, n);
00150 *z = A3 * SuperQuadricFunc::sqS (u, e);
00151
00152 *nx= SuperQuadricFunc::sqC (u, 2 - e) * SuperQuadricFunc::sqC (v, 2 - n) / A1;
00153 *ny= SuperQuadricFunc::sqC (u, 2 - e) * SuperQuadricFunc::sqS (v, 2 - n) / A2;
00154 *nz= SuperQuadricFunc::sqS (u, 2 - e) / A3;
00155 }
00156
00157 void SuperQuadric::solidEllipsoid ()
00158 {
00159
00160
00161
00162
00163
00164 float U, dU, V, dV;
00165 float S, dS, T, dT;
00166 int X, Y;
00167 float x, y, z;
00168 float nx, ny, nz;
00169
00170
00171 dU = (float)(its_u2 - its_u1) / (float)its_u_segs;
00172 dV = (float)(its_v2 - its_v1) / (float)its_v_segs;
00173 dS = (float)(its_s2 - its_s1) / (float)its_u_segs;
00174 dT = (float)(its_t2 - its_t1) / (float)its_v_segs;
00175
00176 glDisable (GL_CULL_FACE);
00177 glEnable (GL_NORMALIZE);
00178
00179
00180 if ( itsUseDisplayList )
00181 glNewList ( itsGlListId, GL_COMPILE );
00182
00183
00184 U = its_u1;
00185 S = its_s1;
00186 glBegin ( GL_QUADS );
00187 for ( Y = 0; Y < its_u_segs; Y++ ) {
00188
00189 V = its_v1;
00190 T = its_t1;
00191 for ( X = 0; X < its_v_segs; X++ ) {
00192
00193 ellipsoid (its_a1, its_a2, its_a3,
00194 U, V,
00195 its_n, its_e,
00196 &x, &y, &z, &nx, &ny, &nz );
00197 glNormal3f ( nx, ny, nz );
00198 glTexCoord2f ( S, T );
00199 glVertex3f ( x, y, z );
00200
00201
00202 ellipsoid (its_a1, its_a2, its_a3,
00203 U + dU, V,
00204 its_n, its_e,
00205 &x, &y, &z, &nx, &ny, &nz );
00206 glNormal3f ( nx, ny, nz );
00207 glTexCoord2f ( S + dS, T );
00208 glVertex3f ( x, y, z );
00209
00210
00211 ellipsoid (its_a1, its_a2, its_a3,
00212 U + dU, V + dV,
00213 its_n, its_e,
00214 &x, &y, &z, &nx, &ny, &nz );
00215 glNormal3f ( nx, ny, nz );
00216 glTexCoord2f ( S + dS, T + dT );
00217 glVertex3f ( x, y, z );
00218
00219
00220 ellipsoid (its_a1, its_a2, its_a3,
00221 U, V + dV,
00222 its_n, its_e,
00223 &x, &y, &z, &nx, &ny, &nz );
00224 glNormal3f ( nx, ny, nz );
00225 glTexCoord2f ( S, T + dT );
00226 glVertex3f ( x, y, z );
00227
00228
00229 V += dV;
00230 T += dT;
00231 }
00232
00233 S += dS;
00234 U += dU;
00235 }
00236 glEnd ( );
00237
00238
00239 if ( itsUseDisplayList )
00240 glEndList ( );
00241 glEnable (GL_CULL_FACE);
00242 glDisable (GL_NORMALIZE);
00243
00244 }
00245
00246 void SuperQuadric::solidToroid ()
00247 {
00248 float U, dU, V, dV;
00249 float S, dS, T, dT;
00250 int X, Y;
00251 float x, y, z;
00252 float nx, ny, nz;
00253
00254
00255 dU = (float)(its_u2 - its_u1) / its_u_segs;
00256 dV = (float)(its_v2 - its_v1) / its_v_segs;
00257 dS = (float)(its_s2 - its_s1) / its_u_segs;
00258 dT = (float)(its_t2 - its_t1) / its_v_segs;
00259
00260 glDisable (GL_CULL_FACE);
00261
00262 glEnable (GL_NORMALIZE);
00263
00264
00265 if (itsUseDisplayList )
00266 glNewList ( itsGlListId, GL_COMPILE );
00267
00268
00269 U = its_u1;
00270 S = its_s1;
00271 glBegin ( GL_QUADS );
00272 for ( Y = 0; Y < its_u_segs; Y++ ) {
00273
00274 V = its_v1;
00275 T = its_t1;
00276 for ( X = 0; X < its_v_segs; X++ ) {
00277
00278 toroid ( its_a1, its_a2, its_a3,
00279 U, V,
00280 its_n, its_e, its_alpha,
00281 &x, &y, &z,
00282 &nx, &ny, &nz );
00283
00284 glNormal3f ( nx, ny, nz );
00285 glTexCoord2f ( S, T );
00286 glVertex3f ( x, y, z );
00287
00288
00289 toroid ( its_a1, its_a2, its_a3,
00290 U + dU, V,
00291 its_n, its_e, its_alpha,
00292 &x, &y, &z, &nx, &ny, &nz );
00293 glNormal3f ( nx, ny, nz );
00294 glTexCoord2f ( S + dS, T );
00295 glVertex3f ( x, y, z );
00296
00297
00298 toroid ( its_a1, its_a2, its_a3,
00299 U + dU, V + dV,
00300 its_n, its_e, its_alpha,
00301 &x, &y, &z, &nx, &ny, &nz );
00302 glNormal3f ( nx, ny, nz );
00303 glTexCoord2f ( S + dS, T + dT );
00304 glVertex3f ( x, y, z );
00305
00306
00307 toroid ( its_a1, its_a2, its_a3,
00308 U, V + dV,
00309 its_n, its_e, its_alpha,
00310 &x, &y, &z, &nx, &ny, &nz );
00311 glNormal3f ( nx, ny, nz );
00312 glTexCoord2f ( S, T + dT);
00313 glVertex3f ( x, y, z );
00314
00315
00316 V += dV;
00317 T += dT;
00318 }
00319
00320 S += dS;
00321 U += dU;
00322 }
00323 glEnd ( );
00324
00325
00326 if ( itsUseDisplayList )
00327 glEndList ( );
00328 glEnable (GL_CULL_FACE);
00329 glDisable (GL_NORMALIZE);
00330 }
00331
00332 float SuperQuadric::ellipsoidInsideOut (float x, float y, float z )
00333 {
00334 float result;
00335 result = powf ( powf ( x / its_a1, 2 / its_e ) +
00336 powf ( y / its_a2, 2 / its_e ), its_e / its_n ) +
00337 powf ( z / its_a3, 2 / its_n );
00338 return result;
00339 }
00340
00341 float SuperQuadric::toroidInsideOut ( float x, float y, float z )
00342 {
00343 float result;
00344 result = powf ( powf ( powf ( x / its_a1, 2 / its_e ) + powf ( y / its_a2, 2 / its_e ),
00345 its_e / 2 ) - its_alpha, 2 / its_n ) + powf ( z / its_a3, 2 / its_n );
00346 return result;
00347 }
00348
00349 void SuperQuadric::solidSphere ( float radius ) {
00350 its_a1 = its_a2 = its_a3 = radius;
00351 its_n = 1.0f;
00352 its_e = 1.0f;
00353 its_u1 = -M_PI / 2;
00354 its_u2 = M_PI / 2;
00355 its_v1 = -M_PI;
00356 its_v2 = M_PI;
00357 its_s1 = 0.0f;
00358 its_t1 = 0.0f;
00359 its_s2 = 1.0f;
00360 its_t2 = 1.0f;
00361 solidEllipsoid ();
00362 }
00363
00364 void SuperQuadric::solidCylinder ( float radius ) {
00365 its_a1 = radius;
00366 its_a2 = radius;
00367 its_a3 = radius;
00368 its_n = 0.0f;
00369 its_e = 1.0f;
00370 its_u1 = -M_PI / 2;
00371 its_u2 = M_PI / 2;
00372 its_v1 = -M_PI;
00373 its_v2 = M_PI;
00374 its_s1 = 0.0f;
00375 its_t1 = 0.0f;
00376 its_s2 = 1.0f;
00377 its_t2 = 1.0f;
00378 solidEllipsoid();
00379 }
00380
00381 void SuperQuadric::solidStar ( float radius ) {
00382
00383 its_a1 = its_a2 = its_a3 = radius;
00384 its_n = 4.0f;
00385 its_e = 4.0f;
00386 its_u1 = -M_PI / 2;
00387 its_u2 = M_PI / 2;
00388 its_v1 = -M_PI;
00389 its_v2 = M_PI;
00390 its_s1 = 0.0f;
00391 its_t1 = 0.0f;
00392 its_s2 = 1.0f;
00393 its_t2 = 1.0f;
00394 solidEllipsoid();
00395 }
00396
00397 void SuperQuadric::solidDoublePyramid ( float radius ) {
00398 its_a1 = its_a2 = its_a3 = radius;
00399 its_n = 2.0f;
00400 its_e = 2.0f;
00401 its_u1 = -M_PI / 2;
00402 its_u2 = M_PI / 2;
00403 its_v1 = -M_PI;
00404 its_v2 = M_PI;
00405 its_s1 = 0.0f;
00406 its_t1 = 0.0f;
00407 its_s2 = 1.0f;
00408 its_t2 = 1.0f;
00409 solidEllipsoid();
00410 }
00411
00412 void SuperQuadric::solidTorus ( float radius1, float radius2 )
00413 {
00414 its_a1 = its_a2 = its_a3 = (radius1 + radius2)/2.0f;
00415 its_alpha = radius2;
00416 its_n = 1.0f;
00417 its_e = 1.0f;
00418 its_u1 = -M_PI;
00419 its_u2 = M_PI;
00420 its_v1 = -M_PI;
00421 its_v2 = M_PI;
00422 its_s1 = 0.0f;
00423 its_t1 = 0.0f;
00424 its_s2 = 1.0f;
00425 its_t2 = 1.0f;
00426 solidToroid();
00427 }
00428
00429 void SuperQuadric::solidPineappleSlice ( float radius1, float radius2 )
00430 {
00431 its_a1 = its_a2 = its_a3 = (radius1 + radius2)/2.0f;
00432 its_alpha = radius2;
00433 its_n = 0.0f;
00434 its_e = 1.0f;
00435 its_u1 = -M_PI;
00436 its_u2 = M_PI;
00437 its_v1 = -M_PI;
00438 its_v2 = M_PI;
00439 its_s1 = 0.0f;
00440 its_t1 = 0.0f;
00441 its_s2 = 1.0f;
00442 its_t2 = 1.0f;
00443 solidToroid();
00444 }
00445
00446 void SuperQuadric::solidPillow ( float radius ) {
00447 its_a1 = its_a2 = its_a3 = radius;
00448 its_n = 1.0f;
00449 its_e = 0.0f;
00450 its_u1 = -M_PI / 2;
00451 its_u2 = M_PI / 2;
00452 its_v1 = -M_PI;
00453 its_v2 = M_PI;
00454 its_s1 = 0.0f;
00455 its_t1 = 0.0f;
00456 its_s2 = 1.0f;
00457 its_t2 = 1.0f;
00458 solidEllipsoid();
00459 }
00460
00461 void SuperQuadric::solidSquareTorus ( float radius1, float radius2 )
00462 {
00463 its_a1 = its_a2 = its_a3 = (radius1 + radius2)/2.0f;
00464 its_alpha = radius2;
00465 its_n = 0.2f;
00466 its_e = 0.2f;
00467 its_u1 = -M_PI;
00468 its_u2 = M_PI;
00469 its_v1 = -M_PI;
00470 its_v2 = M_PI;
00471 its_s1 = 0.0f;
00472 its_t1 = 0.0f;
00473 its_s2 = 1.0f;
00474 its_t2 = 1.0f;
00475 solidToroid();
00476 }
00477
00478 void SuperQuadric::solidPinchedTorus ( float radius1, float radius2 )
00479 {
00480 its_a1 = its_a2 = its_a3 = (radius1 + radius2)/2.0f;
00481 its_alpha = radius2;
00482 its_n = 1.0f;
00483 its_e = 4.0f;
00484 its_u1 = -M_PI;
00485 its_u2 = M_PI;
00486 its_v1 = -M_PI;
00487 its_v2 = M_PI;
00488 its_s1 = 0.0f;
00489 its_t1 = 0.0f;
00490 its_s2 = 1.0f;
00491 its_t2 = 1.0f;
00492 solidToroid();
00493 }
00494
00495 void SuperQuadric::solidRoundCube ( float radius ) {
00496 its_a1 = its_a2 = its_a3 = radius;
00497 its_n = 0.2f;
00498 its_e = 0.2f;
00499 its_u1 = -M_PI / 2;
00500 its_u2 = M_PI / 2;
00501 its_v1 = -M_PI;
00502 its_v2 = M_PI;
00503 its_s1 = 0.0f;
00504 its_t1 = 0.0f;
00505 its_s2 = 1.0f;
00506 its_t2 = 1.0f;
00507 solidEllipsoid();
00508 }
00509
00510 #endif