|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 /* 00002 * freeglut_geometry.c 00003 * 00004 * Freeglut geometry rendering methods. 00005 * 00006 * Copyright (c) 1999-2010 Pawel W. Olszta. All Rights Reserved. 00007 * Written by Pawel W. Olszta, <olszta@sourceforge.net> 00008 * Creation date: Fri Dec 3 1999 00009 * 00010 * Permission is hereby granted, free of charge, to any person obtaining a 00011 * copy of this software and associated documentation files (the "Software"), 00012 * to deal in the Software without restriction, including without limitation 00013 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00014 * and/or sell copies of the Software, and to permit persons to whom the 00015 * Software is furnished to do so, subject to the following conditions: 00016 * 00017 * The above copyright notice and this permission notice shall be included 00018 * in all copies or substantial portions of the Software. 00019 * 00020 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00021 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00022 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00023 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 00024 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00025 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00026 */ 00027 00028 #include <FL/glut.H> 00029 #include <FL/math.h> 00030 #include <stdlib.h> 00031 00032 /* 00033 * TODO BEFORE THE STABLE RELEASE: 00034 * 00035 * Following functions have been contributed by Andreas Umbach. 00036 * 00037 * glutWireCube() -- looks OK 00038 * glutSolidCube() -- OK 00039 * 00040 * Those functions have been implemented by John Fay. 00041 * 00042 * glutWireTorus() -- looks OK 00043 * glutSolidTorus() -- looks OK 00044 * glutWireDodecahedron() -- looks OK 00045 * glutSolidDodecahedron() -- looks OK 00046 * glutWireOctahedron() -- looks OK 00047 * glutSolidOctahedron() -- looks OK 00048 * glutWireTetrahedron() -- looks OK 00049 * glutSolidTetrahedron() -- looks OK 00050 * glutWireIcosahedron() -- looks OK 00051 * glutSolidIcosahedron() -- looks OK 00052 * 00053 * The Following functions have been updated by Nigel Stewart, based 00054 * on FreeGLUT 2.0.0 implementations: 00055 * 00056 * glutWireSphere() -- looks OK 00057 * glutSolidSphere() -- looks OK 00058 * glutWireCone() -- looks OK 00059 * glutSolidCone() -- looks OK 00060 */ 00061 00062 00063 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */ 00064 00065 /* 00066 * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch> 00067 */ 00068 void glutWireCube( GLdouble dSize ) 00069 { 00070 double size = dSize * 0.5; 00071 00072 # define V(a,b,c) glVertex3d( a size, b size, c size ); 00073 # define N(a,b,c) glNormal3d( a, b, c ); 00074 00075 /* PWO: I dared to convert the code to use macros... */ 00076 glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd(); 00077 glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd(); 00078 glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd(); 00079 glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd(); 00080 glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd(); 00081 glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd(); 00082 00083 # undef V 00084 # undef N 00085 } 00086 00087 /* 00088 * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch> 00089 */ 00090 void glutSolidCube( GLdouble dSize ) 00091 { 00092 double size = dSize * 0.5; 00093 00094 # define V(a,b,c) glVertex3d( a size, b size, c size ); 00095 # define N(a,b,c) glNormal3d( a, b, c ); 00096 00097 /* PWO: Again, I dared to convert the code to use macros... */ 00098 glBegin( GL_QUADS ); 00099 N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); 00100 N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); 00101 N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); 00102 N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); 00103 N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); 00104 N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); 00105 glEnd(); 00106 00107 # undef V 00108 # undef N 00109 } 00110 00111 /* 00112 * Compute lookup table of cos and sin values forming a cirle 00113 * 00114 * Notes: 00115 * It is the responsibility of the caller to free these tables 00116 * The size of the table is (n+1) to form a connected loop 00117 * The last entry is exactly the same as the first 00118 * The sign of n can be flipped to get the reverse loop 00119 */ 00120 00121 static void fghCircleTable(double **sint,double **cost,const int n) 00122 { 00123 int i; 00124 00125 /* Table size, the sign of n flips the circle direction */ 00126 00127 const int size = abs(n); 00128 00129 /* Determine the angle between samples */ 00130 00131 const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n ); 00132 00133 /* Allocate memory for n samples, plus duplicate of first entry at the end */ 00134 00135 *sint = (double *) calloc(sizeof(double), size+1); 00136 *cost = (double *) calloc(sizeof(double), size+1); 00137 00138 /* Bail out if memory allocation fails, fgError never returns */ 00139 00140 if (!(*sint) || !(*cost)) 00141 { 00142 if (*sint) free(*sint); 00143 if (*cost) free(*cost); 00144 return; 00145 } 00146 00147 /* Compute cos and sin around the circle */ 00148 00149 (*sint)[0] = 0.0; 00150 (*cost)[0] = 1.0; 00151 00152 for (i=1; i<size; i++) 00153 { 00154 (*sint)[i] = sin(angle*i); 00155 (*cost)[i] = cos(angle*i); 00156 } 00157 00158 /* Last sample is duplicate of the first */ 00159 00160 (*sint)[size] = (*sint)[0]; 00161 (*cost)[size] = (*cost)[0]; 00162 } 00163 00164 /* 00165 * Draws a solid sphere 00166 */ 00167 void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks) 00168 { 00169 int i,j; 00170 00171 /* Adjust z and radius as stacks are drawn. */ 00172 00173 double z0,z1; 00174 double r0,r1; 00175 00176 /* Pre-computed circle */ 00177 00178 double *sint1,*cost1; 00179 double *sint2,*cost2; 00180 00181 fghCircleTable(&sint1,&cost1,-slices); 00182 fghCircleTable(&sint2,&cost2,stacks*2); 00183 00184 /* The top stack is covered with a triangle fan */ 00185 00186 z0 = 1.0; 00187 z1 = cost2[(stacks>0)?1:0]; 00188 r0 = 0.0; 00189 r1 = sint2[(stacks>0)?1:0]; 00190 00191 glBegin(GL_TRIANGLE_FAN); 00192 00193 glNormal3d(0,0,1); 00194 glVertex3d(0,0,radius); 00195 00196 for (j=slices; j>=0; j--) 00197 { 00198 glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); 00199 glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); 00200 } 00201 00202 glEnd(); 00203 00204 /* Cover each stack with a quad strip, except the top and bottom stacks */ 00205 00206 for( i=1; i<stacks-1; i++ ) 00207 { 00208 z0 = z1; z1 = cost2[i+1]; 00209 r0 = r1; r1 = sint2[i+1]; 00210 00211 glBegin(GL_QUAD_STRIP); 00212 00213 for(j=0; j<=slices; j++) 00214 { 00215 glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); 00216 glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); 00217 glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 ); 00218 glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius); 00219 } 00220 00221 glEnd(); 00222 } 00223 00224 /* The bottom stack is covered with a triangle fan */ 00225 00226 z0 = z1; 00227 r0 = r1; 00228 00229 glBegin(GL_TRIANGLE_FAN); 00230 00231 glNormal3d(0,0,-1); 00232 glVertex3d(0,0,-radius); 00233 00234 for (j=0; j<=slices; j++) 00235 { 00236 glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 ); 00237 glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius); 00238 } 00239 00240 glEnd(); 00241 00242 /* Release sin and cos tables */ 00243 00244 free(sint1); 00245 free(cost1); 00246 free(sint2); 00247 free(cost2); 00248 } 00249 00250 /* 00251 * Draws a wire sphere 00252 */ 00253 void glutWireSphere(GLdouble radius, GLint slices, GLint stacks) 00254 { 00255 int i,j; 00256 00257 /* Adjust z and radius as stacks and slices are drawn. */ 00258 00259 double r; 00260 double x,y,z; 00261 00262 /* Pre-computed circle */ 00263 00264 double *sint1,*cost1; 00265 double *sint2,*cost2; 00266 00267 fghCircleTable(&sint1,&cost1,-slices ); 00268 fghCircleTable(&sint2,&cost2, stacks*2); 00269 00270 /* Draw a line loop for each stack */ 00271 00272 for (i=1; i<stacks; i++) 00273 { 00274 z = cost2[i]; 00275 r = sint2[i]; 00276 00277 glBegin(GL_LINE_LOOP); 00278 00279 for(j=0; j<=slices; j++) 00280 { 00281 x = cost1[j]; 00282 y = sint1[j]; 00283 00284 glNormal3d(x,y,z); 00285 glVertex3d(x*r*radius,y*r*radius,z*radius); 00286 } 00287 00288 glEnd(); 00289 } 00290 00291 /* Draw a line loop for each slice */ 00292 00293 for (i=0; i<slices; i++) 00294 { 00295 glBegin(GL_LINE_STRIP); 00296 00297 for(j=0; j<=stacks; j++) 00298 { 00299 x = cost1[i]*sint2[j]; 00300 y = sint1[i]*sint2[j]; 00301 z = cost2[j]; 00302 00303 glNormal3d(x,y,z); 00304 glVertex3d(x*radius,y*radius,z*radius); 00305 } 00306 00307 glEnd(); 00308 } 00309 00310 /* Release sin and cos tables */ 00311 00312 free(sint1); 00313 free(cost1); 00314 free(sint2); 00315 free(cost2); 00316 } 00317 00318 /* 00319 * Draws a solid cone 00320 */ 00321 void glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ) 00322 { 00323 int i,j; 00324 00325 /* Step in z and radius as stacks are drawn. */ 00326 00327 double z0,z1; 00328 double r0,r1; 00329 00330 const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); 00331 const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); 00332 00333 /* Scaling factors for vertex normals */ 00334 00335 const double cosn = ( height / sqrt ( height * height + base * base )); 00336 const double sinn = ( base / sqrt ( height * height + base * base )); 00337 00338 /* Pre-computed circle */ 00339 00340 double *sint,*cost; 00341 00342 fghCircleTable(&sint,&cost,-slices); 00343 00344 /* Cover the circular base with a triangle fan... */ 00345 00346 z0 = 0.0; 00347 z1 = zStep; 00348 00349 r0 = base; 00350 r1 = r0 - rStep; 00351 00352 glBegin(GL_TRIANGLE_FAN); 00353 00354 glNormal3d(0.0,0.0,-1.0); 00355 glVertex3d(0.0,0.0, z0 ); 00356 00357 for (j=0; j<=slices; j++) 00358 glVertex3d(cost[j]*r0, sint[j]*r0, z0); 00359 00360 glEnd(); 00361 00362 /* Cover each stack with a quad strip, except the top stack */ 00363 00364 for( i=0; i<stacks-1; i++ ) 00365 { 00366 glBegin(GL_QUAD_STRIP); 00367 00368 for(j=0; j<=slices; j++) 00369 { 00370 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn); 00371 glVertex3d(cost[j]*r0, sint[j]*r0, z0 ); 00372 glVertex3d(cost[j]*r1, sint[j]*r1, z1 ); 00373 } 00374 00375 z0 = z1; z1 += zStep; 00376 r0 = r1; r1 -= rStep; 00377 00378 glEnd(); 00379 } 00380 00381 /* The top stack is covered with individual triangles */ 00382 00383 glBegin(GL_TRIANGLES); 00384 00385 glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn); 00386 00387 for (j=0; j<slices; j++) 00388 { 00389 glVertex3d(cost[j+0]*r0, sint[j+0]*r0, z0 ); 00390 glVertex3d(0, 0, height); 00391 glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn ); 00392 glVertex3d(cost[j+1]*r0, sint[j+1]*r0, z0 ); 00393 } 00394 00395 glEnd(); 00396 00397 /* Release sin and cos tables */ 00398 00399 free(sint); 00400 free(cost); 00401 } 00402 00403 /* 00404 * Draws a wire cone 00405 */ 00406 void glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks) 00407 { 00408 int i,j; 00409 00410 /* Step in z and radius as stacks are drawn. */ 00411 00412 double z = 0.0; 00413 double r = base; 00414 00415 const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); 00416 const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 ); 00417 00418 /* Scaling factors for vertex normals */ 00419 00420 const double cosn = ( height / sqrt ( height * height + base * base )); 00421 const double sinn = ( base / sqrt ( height * height + base * base )); 00422 00423 /* Pre-computed circle */ 00424 00425 double *sint,*cost; 00426 00427 fghCircleTable(&sint,&cost,-slices); 00428 00429 /* Draw the stacks... */ 00430 00431 for (i=0; i<stacks; i++) 00432 { 00433 glBegin(GL_LINE_LOOP); 00434 00435 for( j=0; j<slices; j++ ) 00436 { 00437 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn); 00438 glVertex3d(cost[j]*r, sint[j]*r, z ); 00439 } 00440 00441 glEnd(); 00442 00443 z += zStep; 00444 r -= rStep; 00445 } 00446 00447 /* Draw the slices */ 00448 00449 r = base; 00450 00451 glBegin(GL_LINES); 00452 00453 for (j=0; j<slices; j++) 00454 { 00455 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn ); 00456 glVertex3d(cost[j]*r, sint[j]*r, 0.0 ); 00457 glVertex3d(0.0, 0.0, height); 00458 } 00459 00460 glEnd(); 00461 00462 /* Release sin and cos tables */ 00463 00464 free(sint); 00465 free(cost); 00466 } 00467 00468 00469 /* 00470 * Draws a solid cylinder 00471 */ 00472 void glutSolidCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks) 00473 { 00474 int i,j; 00475 00476 /* Step in z and radius as stacks are drawn. */ 00477 00478 double z0,z1; 00479 const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); 00480 00481 /* Pre-computed circle */ 00482 00483 double *sint,*cost; 00484 00485 fghCircleTable(&sint,&cost,-slices); 00486 00487 /* Cover the base and top */ 00488 00489 glBegin(GL_TRIANGLE_FAN); 00490 glNormal3d(0.0, 0.0, -1.0 ); 00491 glVertex3d(0.0, 0.0, 0.0 ); 00492 for (j=0; j<=slices; j++) 00493 glVertex3d(cost[j]*radius, sint[j]*radius, 0.0); 00494 glEnd(); 00495 00496 glBegin(GL_TRIANGLE_FAN); 00497 glNormal3d(0.0, 0.0, 1.0 ); 00498 glVertex3d(0.0, 0.0, height); 00499 for (j=slices; j>=0; j--) 00500 glVertex3d(cost[j]*radius, sint[j]*radius, height); 00501 glEnd(); 00502 00503 /* Do the stacks */ 00504 00505 z0 = 0.0; 00506 z1 = zStep; 00507 00508 for (i=1; i<=stacks; i++) 00509 { 00510 if (i==stacks) 00511 z1 = height; 00512 00513 glBegin(GL_QUAD_STRIP); 00514 for (j=0; j<=slices; j++ ) 00515 { 00516 glNormal3d(cost[j], sint[j], 0.0 ); 00517 glVertex3d(cost[j]*radius, sint[j]*radius, z0 ); 00518 glVertex3d(cost[j]*radius, sint[j]*radius, z1 ); 00519 } 00520 glEnd(); 00521 00522 z0 = z1; z1 += zStep; 00523 } 00524 00525 /* Release sin and cos tables */ 00526 00527 free(sint); 00528 free(cost); 00529 } 00530 00531 /* 00532 * Draws a wire cylinder 00533 */ 00534 void glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks) 00535 { 00536 int i,j; 00537 00538 /* Step in z and radius as stacks are drawn. */ 00539 00540 double z = 0.0; 00541 const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 ); 00542 00543 /* Pre-computed circle */ 00544 00545 double *sint,*cost; 00546 00547 fghCircleTable(&sint,&cost,-slices); 00548 00549 /* Draw the stacks... */ 00550 00551 for (i=0; i<=stacks; i++) 00552 { 00553 if (i==stacks) 00554 z = height; 00555 00556 glBegin(GL_LINE_LOOP); 00557 00558 for( j=0; j<slices; j++ ) 00559 { 00560 glNormal3d(cost[j], sint[j], 0.0); 00561 glVertex3d(cost[j]*radius, sint[j]*radius, z ); 00562 } 00563 00564 glEnd(); 00565 00566 z += zStep; 00567 } 00568 00569 /* Draw the slices */ 00570 00571 glBegin(GL_LINES); 00572 00573 for (j=0; j<slices; j++) 00574 { 00575 glNormal3d(cost[j], sint[j], 0.0 ); 00576 glVertex3d(cost[j]*radius, sint[j]*radius, 0.0 ); 00577 glVertex3d(cost[j]*radius, sint[j]*radius, height); 00578 } 00579 00580 glEnd(); 00581 00582 /* Release sin and cos tables */ 00583 00584 free(sint); 00585 free(cost); 00586 } 00587 00588 /* 00589 * Draws a wire torus 00590 */ 00591 void glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings ) 00592 { 00593 double iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi; 00594 double *vertex, *normal; 00595 int i, j; 00596 double spsi, cpsi, sphi, cphi ; 00597 00598 if ( nSides < 1 ) nSides = 1; 00599 if ( nRings < 1 ) nRings = 1; 00600 00601 /* Allocate the vertices array */ 00602 vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings ); 00603 normal = (double *)calloc( sizeof(double), 3 * nSides * nRings ); 00604 00605 glPushMatrix(); 00606 00607 dpsi = 2.0 * M_PI / (double)nRings ; 00608 dphi = -2.0 * M_PI / (double)nSides ; 00609 psi = 0.0; 00610 00611 for( j=0; j<nRings; j++ ) 00612 { 00613 cpsi = cos ( psi ) ; 00614 spsi = sin ( psi ) ; 00615 phi = 0.0; 00616 00617 for( i=0; i<nSides; i++ ) 00618 { 00619 int offset = 3 * ( j * nSides + i ) ; 00620 cphi = cos ( phi ) ; 00621 sphi = sin ( phi ) ; 00622 *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ; 00623 *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ; 00624 *(vertex + offset + 2) = sphi * iradius ; 00625 *(normal + offset + 0) = cpsi * cphi ; 00626 *(normal + offset + 1) = spsi * cphi ; 00627 *(normal + offset + 2) = sphi ; 00628 phi += dphi; 00629 } 00630 00631 psi += dpsi; 00632 } 00633 00634 for( i=0; i<nSides; i++ ) 00635 { 00636 glBegin( GL_LINE_LOOP ); 00637 00638 for( j=0; j<nRings; j++ ) 00639 { 00640 int offset = 3 * ( j * nSides + i ) ; 00641 glNormal3dv( normal + offset ); 00642 glVertex3dv( vertex + offset ); 00643 } 00644 00645 glEnd(); 00646 } 00647 00648 for( j=0; j<nRings; j++ ) 00649 { 00650 glBegin(GL_LINE_LOOP); 00651 00652 for( i=0; i<nSides; i++ ) 00653 { 00654 int offset = 3 * ( j * nSides + i ) ; 00655 glNormal3dv( normal + offset ); 00656 glVertex3dv( vertex + offset ); 00657 } 00658 00659 glEnd(); 00660 } 00661 00662 free ( vertex ) ; 00663 free ( normal ) ; 00664 glPopMatrix(); 00665 } 00666 00667 /* 00668 * Draws a solid torus 00669 */ 00670 void glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings ) 00671 { 00672 double iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi; 00673 double *vertex, *normal; 00674 int i, j; 00675 double spsi, cpsi, sphi, cphi ; 00676 00677 if ( nSides < 1 ) nSides = 1; 00678 if ( nRings < 1 ) nRings = 1; 00679 00680 /* Increment the number of sides and rings to allow for one more point than surface */ 00681 nSides ++ ; 00682 nRings ++ ; 00683 00684 /* Allocate the vertices array */ 00685 vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings ); 00686 normal = (double *)calloc( sizeof(double), 3 * nSides * nRings ); 00687 00688 glPushMatrix(); 00689 00690 dpsi = 2.0 * M_PI / (double)(nRings - 1) ; 00691 dphi = -2.0 * M_PI / (double)(nSides - 1) ; 00692 psi = 0.0; 00693 00694 for( j=0; j<nRings; j++ ) 00695 { 00696 cpsi = cos ( psi ) ; 00697 spsi = sin ( psi ) ; 00698 phi = 0.0; 00699 00700 for( i=0; i<nSides; i++ ) 00701 { 00702 int offset = 3 * ( j * nSides + i ) ; 00703 cphi = cos ( phi ) ; 00704 sphi = sin ( phi ) ; 00705 *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ; 00706 *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ; 00707 *(vertex + offset + 2) = sphi * iradius ; 00708 *(normal + offset + 0) = cpsi * cphi ; 00709 *(normal + offset + 1) = spsi * cphi ; 00710 *(normal + offset + 2) = sphi ; 00711 phi += dphi; 00712 } 00713 00714 psi += dpsi; 00715 } 00716 00717 glBegin( GL_QUADS ); 00718 for( i=0; i<nSides-1; i++ ) 00719 { 00720 for( j=0; j<nRings-1; j++ ) 00721 { 00722 int offset = 3 * ( j * nSides + i ) ; 00723 glNormal3dv( normal + offset ); 00724 glVertex3dv( vertex + offset ); 00725 glNormal3dv( normal + offset + 3 ); 00726 glVertex3dv( vertex + offset + 3 ); 00727 glNormal3dv( normal + offset + 3 * nSides + 3 ); 00728 glVertex3dv( vertex + offset + 3 * nSides + 3 ); 00729 glNormal3dv( normal + offset + 3 * nSides ); 00730 glVertex3dv( vertex + offset + 3 * nSides ); 00731 } 00732 } 00733 00734 glEnd(); 00735 00736 free ( vertex ) ; 00737 free ( normal ) ; 00738 glPopMatrix(); 00739 } 00740 00741 /* 00742 * 00743 */ 00744 void glutWireDodecahedron( void ) 00745 { 00746 /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of 00747 * of a cube. The coordinates of the points are: 00748 * (+-x,0, z); (+-1, 1, 1); (0, z, x ) 00749 * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or 00750 * x = 0.61803398875 and z = 1.61803398875. 00751 */ 00752 glBegin ( GL_LINE_LOOP ) ; 00753 glNormal3d ( 0.0, 0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00754 glEnd () ; 00755 glBegin ( GL_LINE_LOOP ) ; 00756 glNormal3d ( 0.0, 0.525731112119, -0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00757 glEnd () ; 00758 glBegin ( GL_LINE_LOOP ) ; 00759 glNormal3d ( 0.0, -0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00760 glEnd () ; 00761 glBegin ( GL_LINE_LOOP ) ; 00762 glNormal3d ( 0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00763 glEnd () ; 00764 00765 glBegin ( GL_LINE_LOOP ) ; 00766 glNormal3d ( 0.850650808354, 0.0, 0.525731112119 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00767 glEnd () ; 00768 glBegin ( GL_LINE_LOOP ) ; 00769 glNormal3d ( -0.850650808354, 0.0, 0.525731112119 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00770 glEnd () ; 00771 glBegin ( GL_LINE_LOOP ) ; 00772 glNormal3d ( 0.850650808354, 0.0, -0.525731112119 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00773 glEnd () ; 00774 glBegin ( GL_LINE_LOOP ) ; 00775 glNormal3d ( -0.850650808354, 0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00776 glEnd () ; 00777 00778 glBegin ( GL_LINE_LOOP ) ; 00779 glNormal3d ( 0.525731112119, 0.850650808354, 0.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00780 glEnd () ; 00781 glBegin ( GL_LINE_LOOP ) ; 00782 glNormal3d ( 0.525731112119, -0.850650808354, 0.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00783 glEnd () ; 00784 glBegin ( GL_LINE_LOOP ) ; 00785 glNormal3d ( -0.525731112119, 0.850650808354, 0.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00786 glEnd () ; 00787 glBegin ( GL_LINE_LOOP ) ; 00788 glNormal3d ( -0.525731112119, -0.850650808354, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00789 glEnd () ; 00790 } 00791 00792 /* 00793 * 00794 */ 00795 void glutSolidDodecahedron( void ) 00796 { 00797 /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of 00798 * of a cube. The coordinates of the points are: 00799 * (+-x,0, z); (+-1, 1, 1); (0, z, x ) 00800 * where x = (-1 + sqrt(5))/2, z = (1 + sqrt(5))/2 or 00801 * x = 0.61803398875 and z = 1.61803398875. 00802 */ 00803 glBegin ( GL_POLYGON ) ; 00804 glNormal3d ( 0.0, 0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00805 glEnd () ; 00806 glBegin ( GL_POLYGON ) ; 00807 glNormal3d ( 0.0, 0.525731112119, -0.850650808354 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00808 glEnd () ; 00809 glBegin ( GL_POLYGON ) ; 00810 glNormal3d ( 0.0, -0.525731112119, 0.850650808354 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00811 glEnd () ; 00812 glBegin ( GL_POLYGON ) ; 00813 glNormal3d ( 0.0, -0.525731112119, -0.850650808354 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00814 glEnd () ; 00815 00816 glBegin ( GL_POLYGON ) ; 00817 glNormal3d ( 0.850650808354, 0.0, 0.525731112119 ) ; glVertex3d ( 0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00818 glEnd () ; 00819 glBegin ( GL_POLYGON ) ; 00820 glNormal3d ( -0.850650808354, 0.0, 0.525731112119 ) ; glVertex3d ( -0.61803398875, 0.0, 1.61803398875 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00821 glEnd () ; 00822 glBegin ( GL_POLYGON ) ; 00823 glNormal3d ( 0.850650808354, 0.0, -0.525731112119 ) ; glVertex3d ( 0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00824 glEnd () ; 00825 glBegin ( GL_POLYGON ) ; 00826 glNormal3d ( -0.850650808354, 0.0, -0.525731112119 ) ; glVertex3d ( -0.61803398875, 0.0, -1.61803398875 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00827 glEnd () ; 00828 00829 glBegin ( GL_POLYGON ) ; 00830 glNormal3d ( 0.525731112119, 0.850650808354, 0.0 ) ; glVertex3d ( 1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( 1.0, 1.0, -1.0 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( 1.0, 1.0, 1.0 ) ; 00831 glEnd () ; 00832 glBegin ( GL_POLYGON ) ; 00833 glNormal3d ( 0.525731112119, -0.850650808354, 0.0 ) ; glVertex3d ( 1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( 1.0, -1.0, 1.0 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 1.0, -1.0, -1.0 ) ; 00834 glEnd () ; 00835 glBegin ( GL_POLYGON ) ; 00836 glNormal3d ( -0.525731112119, 0.850650808354, 0.0 ) ; glVertex3d ( -1.61803398875, 0.61803398875, 0.0 ) ; glVertex3d ( -1.0, 1.0, 1.0 ) ; glVertex3d ( 0.0, 1.61803398875, 0.61803398875 ) ; glVertex3d ( 0.0, 1.61803398875, -0.61803398875 ) ; glVertex3d ( -1.0, 1.0, -1.0 ) ; 00837 glEnd () ; 00838 glBegin ( GL_POLYGON ) ; 00839 glNormal3d ( -0.525731112119, -0.850650808354, 0.0 ) ; glVertex3d ( -1.61803398875, -0.61803398875, 0.0 ) ; glVertex3d ( -1.0, -1.0, -1.0 ) ; glVertex3d ( 0.0, -1.61803398875, -0.61803398875 ) ; glVertex3d ( 0.0, -1.61803398875, 0.61803398875 ) ; glVertex3d ( -1.0, -1.0, 1.0 ) ; 00840 glEnd () ; 00841 } 00842 00843 /* 00844 * 00845 */ 00846 void glutWireOctahedron( void ) 00847 { 00848 #define RADIUS 1.0f 00849 glBegin( GL_LINE_LOOP ); 00850 glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); 00851 glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); 00852 glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); 00853 glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); 00854 glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); 00855 glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); 00856 glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); 00857 glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); 00858 glEnd(); 00859 #undef RADIUS 00860 } 00861 00862 /* 00863 * 00864 */ 00865 void glutSolidOctahedron( void ) 00866 { 00867 #define RADIUS 1.0f 00868 glBegin( GL_TRIANGLES ); 00869 glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); 00870 glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); 00871 glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); 00872 glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); 00873 glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); glVertex3d( 0.0, RADIUS, 0.0 ); 00874 glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, RADIUS, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); 00875 glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0,-RADIUS, 0.0 ); glVertex3d( 0.0, 0.0, RADIUS ); 00876 glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-RADIUS, 0.0, 0.0 ); glVertex3d( 0.0, 0.0,-RADIUS ); glVertex3d( 0.0,-RADIUS, 0.0 ); 00877 glEnd(); 00878 #undef RADIUS 00879 } 00880 00881 /* Magic Numbers: r0 = ( 1, 0, 0 ) 00882 * r1 = ( -1/3, 2 sqrt(2) / 3, 0 ) 00883 * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 ) 00884 * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 ) 00885 * |r0| = |r1| = |r2| = |r3| = 1 00886 * Distance between any two points is 2 sqrt(6) / 3 00887 * 00888 * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface. 00889 */ 00890 00891 #define NUM_TETR_FACES 4 00892 00893 static GLdouble tet_r[4][3] = { { 1.0, 0.0, 0.0 }, 00894 { -0.333333333333, 0.942809041582, 0.0 }, 00895 { -0.333333333333, -0.471404520791, 0.816496580928 }, 00896 { -0.333333333333, -0.471404520791, -0.816496580928 } } ; 00897 00898 static GLint tet_i[4][3] = /* Vertex indices */ 00899 { 00900 { 1, 3, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 0, 1, 2 } 00901 } ; 00902 00903 /* 00904 * 00905 */ 00906 void glutWireTetrahedron( void ) 00907 { 00908 glBegin( GL_LINE_LOOP ) ; 00909 glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ; 00910 glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ; 00911 glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ; 00912 glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ; 00913 glEnd() ; 00914 } 00915 00916 /* 00917 * 00918 */ 00919 void glutSolidTetrahedron( void ) 00920 { 00921 glBegin( GL_TRIANGLES ) ; 00922 glNormal3d ( -tet_r[0][0], -tet_r[0][1], -tet_r[0][2] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[2] ) ; 00923 glNormal3d ( -tet_r[1][0], -tet_r[1][1], -tet_r[1][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[2] ) ; glVertex3dv ( tet_r[3] ) ; 00924 glNormal3d ( -tet_r[2][0], -tet_r[2][1], -tet_r[2][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[3] ) ; glVertex3dv ( tet_r[1] ) ; 00925 glNormal3d ( -tet_r[3][0], -tet_r[3][1], -tet_r[3][2] ) ; glVertex3dv ( tet_r[0] ) ; glVertex3dv ( tet_r[1] ) ; glVertex3dv ( tet_r[2] ) ; 00926 glEnd() ; 00927 } 00928 00929 /* 00930 * 00931 */ 00932 double icos_r[12][3] = { { 1.0, 0.0, 0.0 }, 00933 { 0.447213595500, 0.894427191000, 0.0 }, { 0.447213595500, 0.276393202252, 0.850650808354 }, { 0.447213595500, -0.723606797748, 0.525731112119 }, { 0.447213595500, -0.723606797748, -0.525731112119 }, { 0.447213595500, 0.276393202252, -0.850650808354 }, 00934 { -0.447213595500, -0.894427191000, 0.0 }, { -0.447213595500, -0.276393202252, 0.850650808354 }, { -0.447213595500, 0.723606797748, 0.525731112119 }, { -0.447213595500, 0.723606797748, -0.525731112119 }, { -0.447213595500, -0.276393202252, -0.850650808354 }, 00935 { -1.0, 0.0, 0.0 } } ; 00936 int icos_v [20][3] = { { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 0, 4, 5 }, { 0, 5, 1 }, 00937 { 1, 8, 2 }, { 2, 7, 3 }, { 3, 6, 4 }, { 4, 10, 5 }, { 5, 9, 1 }, 00938 { 1, 9, 8 }, { 2, 8, 7 }, { 3, 7, 6 }, { 4, 6, 10 }, { 5, 10, 9 }, 00939 { 11, 9, 10 }, { 11, 8, 9 }, { 11, 7, 8 }, { 11, 6, 7 }, { 11, 10, 6 } } ; 00940 00941 void glutWireIcosahedron( void ) 00942 { 00943 int i ; 00944 00945 for ( i = 0; i < 20; i++ ) 00946 { 00947 double normal[3] ; 00948 normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ; 00949 normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ; 00950 normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ; 00951 glBegin ( GL_LINE_LOOP ) ; 00952 glNormal3dv ( normal ) ; 00953 glVertex3dv ( icos_r[icos_v[i][0]] ) ; 00954 glVertex3dv ( icos_r[icos_v[i][1]] ) ; 00955 glVertex3dv ( icos_r[icos_v[i][2]] ) ; 00956 glEnd () ; 00957 } 00958 } 00959 00960 /* 00961 * 00962 */ 00963 void glutSolidIcosahedron( void ) 00964 { 00965 int i ; 00966 00967 glBegin ( GL_TRIANGLES ) ; 00968 for ( i = 0; i < 20; i++ ) 00969 { 00970 double normal[3] ; 00971 normal[0] = ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) - ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) ; 00972 normal[1] = ( icos_r[icos_v[i][1]][2] - icos_r[icos_v[i][0]][2] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) - ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][2] - icos_r[icos_v[i][0]][2] ) ; 00973 normal[2] = ( icos_r[icos_v[i][1]][0] - icos_r[icos_v[i][0]][0] ) * ( icos_r[icos_v[i][2]][1] - icos_r[icos_v[i][0]][1] ) - ( icos_r[icos_v[i][1]][1] - icos_r[icos_v[i][0]][1] ) * ( icos_r[icos_v[i][2]][0] - icos_r[icos_v[i][0]][0] ) ; 00974 glNormal3dv ( normal ) ; 00975 glVertex3dv ( icos_r[icos_v[i][0]] ) ; 00976 glVertex3dv ( icos_r[icos_v[i][1]] ) ; 00977 glVertex3dv ( icos_r[icos_v[i][2]] ) ; 00978 } 00979 00980 glEnd () ; 00981 } 00982 00983 /* 00984 * 00985 */ 00986 double rdod_r[14][3] = { { 0.0, 0.0, 1.0 }, 00987 { 0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, 0.707106781187, 0.5 }, { -0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, -0.707106781187, 0.5 }, 00988 { 0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, -0.707106781187, 0.0 }, { 0.707106781187, -0.707106781187, 0.0 }, 00989 { 0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, 0.707106781187, -0.5 }, { -0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, -0.707106781187, -0.5 }, 00990 { 0.0, 0.0, -1.0 } } ; 00991 int rdod_v [12][4] = { { 0, 1, 5, 2 }, { 0, 2, 6, 3 }, { 0, 3, 7, 4 }, { 0, 4, 8, 1 }, 00992 { 5, 10, 6, 2 }, { 6, 11, 7, 3 }, { 7, 12, 8, 4 }, { 8, 9, 5, 1 }, 00993 { 5, 9, 13, 10 }, { 6, 10, 13, 11 }, { 7, 11, 13, 12 }, { 8, 12, 13, 9 } } ; 00994 double rdod_n[12][3] = { 00995 { 0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, -0.353553390594, 0.5 }, { 0.353553390594, -0.353553390594, 0.5 }, 00996 { 0.000000000000, 1.000000000000, 0.0 }, { -1.000000000000, 0.000000000000, 0.0 }, { 0.000000000000, -1.000000000000, 0.0 }, { 1.000000000000, 0.000000000000, 0.0 }, 00997 { 0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, -0.353553390594, -0.5 }, { 0.353553390594, -0.353553390594, -0.5 } 00998 } ; 00999 01000 void glutWireRhombicDodecahedron( void ) 01001 { 01002 int i ; 01003 01004 for ( i = 0; i < 12; i++ ) 01005 { 01006 glBegin ( GL_LINE_LOOP ) ; 01007 glNormal3dv ( rdod_n[i] ) ; 01008 glVertex3dv ( rdod_r[rdod_v[i][0]] ) ; 01009 glVertex3dv ( rdod_r[rdod_v[i][1]] ) ; 01010 glVertex3dv ( rdod_r[rdod_v[i][2]] ) ; 01011 glVertex3dv ( rdod_r[rdod_v[i][3]] ) ; 01012 glEnd () ; 01013 } 01014 } 01015 01016 /* 01017 * 01018 */ 01019 void glutSolidRhombicDodecahedron( void ) 01020 { 01021 int i ; 01022 01023 glBegin ( GL_QUADS ) ; 01024 for ( i = 0; i < 12; i++ ) 01025 { 01026 glNormal3dv ( rdod_n[i] ) ; 01027 glVertex3dv ( rdod_r[rdod_v[i][0]] ) ; 01028 glVertex3dv ( rdod_r[rdod_v[i][1]] ) ; 01029 glVertex3dv ( rdod_r[rdod_v[i][2]] ) ; 01030 glVertex3dv ( rdod_r[rdod_v[i][3]] ) ; 01031 } 01032 01033 glEnd () ; 01034 } 01035 01036 void glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) 01037 { 01038 int i, j ; 01039 01040 if ( num_levels == 0 ) 01041 { 01042 01043 for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) 01044 { 01045 glBegin ( GL_LINE_LOOP ) ; 01046 glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ; 01047 for ( j = 0; j < 3; j++ ) 01048 { 01049 double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ; 01050 double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ; 01051 double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ; 01052 glVertex3d ( x, y, z ) ; 01053 } 01054 01055 glEnd () ; 01056 } 01057 } 01058 else 01059 { 01060 GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */ 01061 num_levels -- ; 01062 scale /= 2.0 ; 01063 for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) 01064 { 01065 local_offset[0] = offset[0] + scale * tet_r[i][0] ; 01066 local_offset[1] = offset[1] + scale * tet_r[i][1] ; 01067 local_offset[2] = offset[2] + scale * tet_r[i][2] ; 01068 glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ; 01069 } 01070 } 01071 } 01072 01073 void glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ) 01074 { 01075 int i, j ; 01076 01077 if ( num_levels == 0 ) 01078 { 01079 glBegin ( GL_TRIANGLES ) ; 01080 01081 for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) 01082 { 01083 glNormal3d ( -tet_r[i][0], -tet_r[i][1], -tet_r[i][2] ) ; 01084 for ( j = 0; j < 3; j++ ) 01085 { 01086 double x = offset[0] + scale * tet_r[tet_i[i][j]][0] ; 01087 double y = offset[1] + scale * tet_r[tet_i[i][j]][1] ; 01088 double z = offset[2] + scale * tet_r[tet_i[i][j]][2] ; 01089 glVertex3d ( x, y, z ) ; 01090 } 01091 } 01092 01093 glEnd () ; 01094 } 01095 else 01096 { 01097 GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */ 01098 num_levels -- ; 01099 scale /= 2.0 ; 01100 for ( i = 0 ; i < NUM_TETR_FACES ; i++ ) 01101 { 01102 local_offset[0] = offset[0] + scale * tet_r[i][0] ; 01103 local_offset[1] = offset[1] + scale * tet_r[i][1] ; 01104 local_offset[2] = offset[2] + scale * tet_r[i][2] ; 01105 glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ; 01106 } 01107 } 01108 } 01109 01110 /*** END OF FILE ***/