4 * Freeglut geometry rendering methods.
6 * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
7 * Written by Pawel W. Olszta, <olszta@sourceforge.net>
8 * Creation date: Fri Dec 3 1999
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include <GL/freeglut.h>
33 #include "freeglut_internal.h"
36 * TODO BEFORE THE STABLE RELEASE:
38 * Following functions have been contributed by Andreas Umbach.
40 * glutWireCube() -- looks OK
41 * glutSolidCube() -- OK
43 * Those functions have been implemented by John Fay.
45 * glutWireTorus() -- looks OK
46 * glutSolidTorus() -- looks OK
47 * glutWireDodecahedron() -- looks OK
48 * glutSolidDodecahedron() -- looks OK
49 * glutWireOctahedron() -- looks OK
50 * glutSolidOctahedron() -- looks OK
51 * glutWireTetrahedron() -- looks OK
52 * glutSolidTetrahedron() -- looks OK
53 * glutWireIcosahedron() -- looks OK
54 * glutSolidIcosahedron() -- looks OK
56 * The Following functions have been updated by Nigel Stewart, based
57 * on FreeGLUT 2.0.0 implementations:
59 * glutWireSphere() -- looks OK
60 * glutSolidSphere() -- looks OK
61 * glutWireCone() -- looks OK
62 * glutSolidCone() -- looks OK
66 /* -- INTERFACE FUNCTIONS -------------------------------------------------- */
69 * Draws a wireframed cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
71 void FGAPIENTRY glutWireCube( GLdouble dSize )
73 double size = dSize * 0.5;
75 # define V(a,b,c) glVertex3d( a size, b size, c size );
76 # define N(a,b,c) glNormal3d( a, b, c );
79 * PWO: I dared to convert the code to use macros...
81 glBegin( GL_LINE_LOOP ); N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+); glEnd();
82 glBegin( GL_LINE_LOOP ); N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+); glEnd();
83 glBegin( GL_LINE_LOOP ); N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+); glEnd();
84 glBegin( GL_LINE_LOOP ); N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-); glEnd();
85 glBegin( GL_LINE_LOOP ); N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+); glEnd();
86 glBegin( GL_LINE_LOOP ); N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-); glEnd();
93 * Draws a solid cube. Code contributed by Andreas Umbach <marvin@dataway.ch>
95 void FGAPIENTRY glutSolidCube( GLdouble dSize )
97 double size = dSize * 0.5;
99 # define V(a,b,c) glVertex3d( a size, b size, c size );
100 # define N(a,b,c) glNormal3d( a, b, c );
103 * PWO: Again, I dared to convert the code to use macros...
106 N( 1.0, 0.0, 0.0); V(+,-,+); V(+,-,-); V(+,+,-); V(+,+,+);
107 N( 0.0, 1.0, 0.0); V(+,+,+); V(+,+,-); V(-,+,-); V(-,+,+);
108 N( 0.0, 0.0, 1.0); V(+,+,+); V(-,+,+); V(-,-,+); V(+,-,+);
109 N(-1.0, 0.0, 0.0); V(-,-,+); V(-,+,+); V(-,+,-); V(-,-,-);
110 N( 0.0,-1.0, 0.0); V(-,-,+); V(-,-,-); V(+,-,-); V(+,-,+);
111 N( 0.0, 0.0,-1.0); V(-,-,-); V(-,+,-); V(+,+,-); V(+,-,-);
119 * Compute lookup table of cos and sin values forming a cirle
122 * It is the responsibility of the caller to free these tables
123 * The size of the table is (n+1) to form a connected loop
124 * The last entry is exactly the same as the first
125 * The sign of n can be flipped to get the reverse loop
128 static void circleTable(double **sint,double **cost,const int n)
132 /* Table size, the sign of n flips the circle direction */
134 const int size = abs(n);
136 /* Determine the angle between samples */
138 const double angle = 2*M_PI/(double)n;
140 /* Allocate memory for n samples, plus duplicate of first entry at the end */
142 *sint = (double *) calloc(sizeof(double), size+1);
143 *cost = (double *) calloc(sizeof(double), size+1);
145 /* Bail out if memory allocation fails, fgError never returns */
147 if (!(*sint) || !(*cost))
151 fgError("Failed to allocate memory in circleTable");
154 /* Compute cos and sin around the circle */
156 for (i=0; i<size; i++)
158 (*sint)[i] = sin(angle*i);
159 (*cost)[i] = cos(angle*i);
162 /* Last sample is duplicate of the first */
164 (*sint)[size] = (*sint)[0];
165 (*cost)[size] = (*cost)[0];
169 * Draws a solid sphere
171 void FGAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
175 /* Adjust z and radius as stacks are drawn. */
180 /* Pre-computed circle */
182 double *sint1,*cost1;
183 double *sint2,*cost2;
184 circleTable(&sint1,&cost1,-slices);
185 circleTable(&sint2,&cost2,stacks*2);
187 /* The top stack is covered with a triangle fan */
194 glBegin(GL_TRIANGLE_FAN);
197 glVertex3d(0,0,radius);
199 for (j=slices; j>=0; j--)
201 glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
202 glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
207 /* Cover each stack with a quad strip, except the top and bottom stacks */
209 for( i=1; i<stacks-1; i++ )
211 z0 = z1; z1 = cost2[i+1];
212 r0 = r1; r1 = sint2[i+1];
214 glBegin(GL_QUAD_STRIP);
216 for(j=0; j<=slices; j++)
218 glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 );
219 glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius);
220 glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
221 glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
227 /* The bottom stack is covered with a triangle fan */
232 glBegin(GL_TRIANGLE_FAN);
235 glVertex3d(0,0,-radius);
237 for (j=0; j<=slices; j++)
239 glNormal3d(cost1[j]*r0, sint1[j]*r0, z0 );
240 glVertex3d(cost1[j]*r0*radius, sint1[j]*r0*radius, z0*radius);
245 /* Release sin and cos tables */
254 * Draws a wire sphere
256 void FGAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
260 /* Adjust z and radius as stacks and slices are drawn. */
265 /* Pre-computed circle */
267 double *sint1,*cost1;
268 double *sint2,*cost2;
269 circleTable(&sint1,&cost1,-slices );
270 circleTable(&sint2,&cost2, stacks*2);
272 /* Draw a line loop for each stack */
274 for (i=1; i<stacks; i++)
279 glBegin(GL_LINE_LOOP);
281 for(j=0; j<=slices; j++)
287 glVertex3d(x*r*radius,y*r*radius,z*radius);
293 /* Draw a line loop for each slice */
295 for (i=0; i<slices; i++)
297 glBegin(GL_LINE_STRIP);
299 for(j=0; j<=stacks; j++)
301 x = cost1[i]*sint2[j];
302 y = sint1[i]*sint2[j];
306 glVertex3d(x*radius,y*radius,z*radius);
312 /* Release sin and cos tables */
323 void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
327 /* Step in z and radius as stacks are drawn. */
332 const double zStep = height/stacks;
333 const double rStep = base/stacks;
335 /* Scaling factors for vertex normals */
337 const double cosn = ( height / sqrt ( height * height + base * base ));
338 const double sinn = ( base / sqrt ( height * height + base * base ));
340 /* Pre-computed circle */
343 circleTable(&sint,&cost,-slices);
345 /* Cover the circular base with a triangle fan... */
353 glBegin(GL_TRIANGLE_FAN);
355 glNormal3d(0.0,0.0,-1.0);
356 glVertex3d(0.0,0.0, z0 );
358 for (j=0; j<=slices; j++)
359 glVertex3d(cost[j]*r0, sint[j]*r0, z0);
363 /* Cover each stack with a quad strip, except the top stack */
365 for( i=0; i<stacks-1; i++ )
367 glBegin(GL_QUAD_STRIP);
369 for(j=0; j<=slices; j++)
371 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
372 glVertex3d(cost[j]*r0, sint[j]*r0, z0 );
373 glVertex3d(cost[j]*r1, sint[j]*r1, z1 );
376 z0 = z1; z1 += zStep;
377 r0 = r1; r1 -= rStep;
382 /* The top stack is covered with individual triangles */
384 glBegin(GL_TRIANGLES);
386 glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);
388 for (j=0; j<slices; j++)
390 glVertex3d(cost[j+0]*r0, sint[j+0]*r0, z0 );
391 glVertex3d(0, 0, height);
392 glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn );
393 glVertex3d(cost[j+1]*r0, sint[j+1]*r0, z0 );
398 /* Release sin and cos tables */
407 void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks)
411 /* Step in z and radius as stacks are drawn. */
416 const double zStep = height/stacks;
417 const double rStep = base/stacks;
419 /* Scaling factors for vertex normals */
421 const double cosn = ( height / sqrt ( height * height + base * base ));
422 const double sinn = ( base / sqrt ( height * height + base * base ));
424 /* Pre-computed circle */
427 circleTable(&sint,&cost,-slices);
429 /* Draw the stacks... */
431 for (i=0; i<stacks; i++)
433 glBegin(GL_LINE_LOOP);
435 for( j=0; j<slices; j++ )
437 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
438 glVertex3d(cost[j]*r, sint[j]*r, z );
447 /* Draw the slices */
453 for (j=0; j<slices; j++)
455 glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn );
456 glVertex3d(cost[j]*r, sint[j]*r, 0.0 );
457 glVertex3d(0.0, 0.0, height);
462 /* Release sin and cos tables */
470 * Draws a solid cylinder
472 void FGAPIENTRY glutSolidCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
476 /* Step in z and radius as stacks are drawn. */
479 const double zStep = height/stacks;
481 /* Pre-computed circle */
484 circleTable(&sint,&cost,-slices);
486 /* Cover the base and top */
488 glBegin(GL_TRIANGLE_FAN);
489 glNormal3d(0.0, 0.0, -1.0 );
490 glVertex3d(0.0, 0.0, 0.0 );
491 for (j=0; j<=slices; j++)
492 glVertex3d(cost[j]*radius, sint[j]*radius, 0.0);
495 glBegin(GL_TRIANGLE_FAN);
496 glNormal3d(0.0, 0.0, 1.0 );
497 glVertex3d(0.0, 0.0, height);
498 for (j=slices; j>=0; j--)
499 glVertex3d(cost[j]*radius, sint[j]*radius, height);
507 for (i=1; i<=stacks; i++)
512 glBegin(GL_QUAD_STRIP);
513 for (j=0; j<=slices; j++ )
515 glNormal3d(cost[j], sint[j], 0.0 );
516 glVertex3d(cost[j]*radius, sint[j]*radius, z0 );
517 glVertex3d(cost[j]*radius, sint[j]*radius, z1 );
521 z0 = z1; z1 += zStep;
524 /* Release sin and cos tables */
531 * Draws a wire cylinder
533 void FGAPIENTRY glutWireCylinder(GLdouble radius, GLdouble height, GLint slices, GLint stacks)
537 /* Step in z and radius as stacks are drawn. */
540 const double zStep = height/stacks;
542 /* Pre-computed circle */
545 circleTable(&sint,&cost,-slices);
547 /* Draw the stacks... */
549 for (i=0; i<=stacks; i++)
554 glBegin(GL_LINE_LOOP);
556 for( j=0; j<slices; j++ )
558 glNormal3d(cost[j], sint[j], 0.0);
559 glVertex3d(cost[j]*radius, sint[j]*radius, z );
567 /* Draw the slices */
571 for (j=0; j<slices; j++)
573 glNormal3d(cost[j], sint[j], 0.0 );
574 glVertex3d(cost[j]*radius, sint[j]*radius, 0.0 );
575 glVertex3d(cost[j]*radius, sint[j]*radius, height);
580 /* Release sin and cos tables */
589 void FGAPIENTRY glutWireTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
591 double iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
592 double *vertex, *normal;
594 double spsi, cpsi, sphi, cphi ;
597 * Allocate the vertices array
599 vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
600 normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
604 dpsi = 2.0 * M_PI / (double)nRings ;
605 dphi = -2.0 * M_PI / (double)nSides ;
608 for( j=0; j<nRings; j++ )
614 for( i=0; i<nSides; i++ )
616 int offset = 3 * ( j * nSides + i ) ;
619 *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
620 *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
621 *(vertex + offset + 2) = sphi * iradius ;
622 *(normal + offset + 0) = cpsi * cphi ;
623 *(normal + offset + 1) = spsi * cphi ;
624 *(normal + offset + 2) = sphi ;
631 for( i=0; i<nSides; i++ )
633 glBegin( GL_LINE_LOOP );
635 for( j=0; j<nRings; j++ )
637 int offset = 3 * ( j * nSides + i ) ;
638 glNormal3dv( normal + offset );
639 glVertex3dv( vertex + offset );
645 for( j=0; j<nRings; j++ )
647 glBegin(GL_LINE_LOOP);
649 for( i=0; i<nSides; i++ )
651 int offset = 3 * ( j * nSides + i ) ;
652 glNormal3dv( normal + offset );
653 glVertex3dv( vertex + offset );
665 * Draws a solid torus
667 void FGAPIENTRY glutSolidTorus( GLdouble dInnerRadius, GLdouble dOuterRadius, GLint nSides, GLint nRings )
669 double iradius = dInnerRadius, oradius = dOuterRadius, phi, psi, dpsi, dphi;
670 double *vertex, *normal;
672 double spsi, cpsi, sphi, cphi ;
675 * Increment the number of sides and rings to allow for one more point than surface
681 * Allocate the vertices array
683 vertex = (double *)calloc( sizeof(double), 3 * nSides * nRings );
684 normal = (double *)calloc( sizeof(double), 3 * nSides * nRings );
688 dpsi = 2.0 * M_PI / (double)(nRings - 1) ;
689 dphi = -2.0 * M_PI / (double)(nSides - 1) ;
692 for( j=0; j<nRings; j++ )
698 for( i=0; i<nSides; i++ )
700 int offset = 3 * ( j * nSides + i ) ;
703 *(vertex + offset + 0) = cpsi * ( oradius + cphi * iradius ) ;
704 *(vertex + offset + 1) = spsi * ( oradius + cphi * iradius ) ;
705 *(vertex + offset + 2) = sphi * iradius ;
706 *(normal + offset + 0) = cpsi * cphi ;
707 *(normal + offset + 1) = spsi * cphi ;
708 *(normal + offset + 2) = sphi ;
716 for( i=0; i<nSides-1; i++ )
718 for( j=0; j<nRings-1; j++ )
720 int offset = 3 * ( j * nSides + i ) ;
721 glNormal3dv( normal + offset );
722 glVertex3dv( vertex + offset );
723 glNormal3dv( normal + offset + 3 );
724 glVertex3dv( vertex + offset + 3 );
725 glNormal3dv( normal + offset + 3 * nSides + 3 );
726 glVertex3dv( vertex + offset + 3 * nSides + 3 );
727 glNormal3dv( normal + offset + 3 * nSides );
728 glVertex3dv( vertex + offset + 3 * nSides );
742 void FGAPIENTRY glutWireDodecahedron( void )
744 /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of
745 * of a cube. The coordinates of the points are:
746 * (+-x,0, z); (+-1, 1, 1); (0, z, x )
747 * where x = 0.61803398875 and z = 1.61803398875.
749 glBegin ( GL_LINE_LOOP ) ;
750 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 ) ;
752 glBegin ( GL_LINE_LOOP ) ;
753 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 ) ;
755 glBegin ( GL_LINE_LOOP ) ;
756 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 ) ;
758 glBegin ( GL_LINE_LOOP ) ;
759 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 ) ;
762 glBegin ( GL_LINE_LOOP ) ;
763 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 ) ;
765 glBegin ( GL_LINE_LOOP ) ;
766 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 ) ;
768 glBegin ( GL_LINE_LOOP ) ;
769 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 ) ;
771 glBegin ( GL_LINE_LOOP ) ;
772 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 ) ;
775 glBegin ( GL_LINE_LOOP ) ;
776 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 ) ;
778 glBegin ( GL_LINE_LOOP ) ;
779 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 ) ;
781 glBegin ( GL_LINE_LOOP ) ;
782 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 ) ;
784 glBegin ( GL_LINE_LOOP ) ;
785 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 ) ;
792 void FGAPIENTRY glutSolidDodecahedron( void )
794 /* Magic Numbers: It is possible to create a dodecahedron by attaching two pentagons to each face of
795 * of a cube. The coordinates of the points are:
796 * (+-x,0, z); (+-1, 1, 1); (0, z, x )
797 * where x = 0.61803398875 and z = 1.61803398875.
799 glBegin ( GL_POLYGON ) ;
800 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 ) ;
802 glBegin ( GL_POLYGON ) ;
803 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 ) ;
805 glBegin ( GL_POLYGON ) ;
806 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 ) ;
808 glBegin ( GL_POLYGON ) ;
809 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 ) ;
812 glBegin ( GL_POLYGON ) ;
813 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 ) ;
815 glBegin ( GL_POLYGON ) ;
816 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 ) ;
818 glBegin ( GL_POLYGON ) ;
819 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 ) ;
821 glBegin ( GL_POLYGON ) ;
822 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 ) ;
825 glBegin ( GL_POLYGON ) ;
826 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 ) ;
828 glBegin ( GL_POLYGON ) ;
829 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 ) ;
831 glBegin ( GL_POLYGON ) ;
832 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 ) ;
834 glBegin ( GL_POLYGON ) ;
835 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 ) ;
842 void FGAPIENTRY glutWireOctahedron( void )
845 glBegin( GL_LINE_LOOP );
846 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 );
847 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 );
848 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 );
849 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 );
850 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 );
851 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 );
852 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 );
853 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 );
861 void FGAPIENTRY glutSolidOctahedron( void )
864 glBegin( GL_TRIANGLES );
865 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 );
866 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 );
867 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 );
868 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 );
869 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 );
870 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 );
871 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 );
872 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 );
880 void FGAPIENTRY glutWireTetrahedron( void )
882 /* Magic Numbers: r0 = ( 1, 0, 0 )
883 * r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
884 * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
885 * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
886 * |r0| = |r1| = |r2| = |r3| = 1
887 * Distance between any two points is 2 sqrt(6) / 3
889 * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface.
892 double r0[3] = { 1.0, 0.0, 0.0 } ;
893 double r1[3] = { -0.333333333333, 0.942809041582, 0.0 } ;
894 double r2[3] = { -0.333333333333, -0.471404520791, 0.816496580928 } ;
895 double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ;
897 glBegin( GL_LINE_LOOP ) ;
898 glNormal3d ( -1.0, 0.0, 0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ;
899 glNormal3d ( 0.333333333333, -0.942809041582, 0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ;
900 glNormal3d ( 0.333333333333, 0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ;
901 glNormal3d ( 0.333333333333, 0.471404520791, 0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ;
908 void FGAPIENTRY glutSolidTetrahedron( void )
910 /* Magic Numbers: r0 = ( 1, 0, 0 )
911 * r1 = ( -1/3, 2 sqrt(2) / 3, 0 )
912 * r2 = ( -1/3, -sqrt(2) / 3, sqrt(6) / 3 )
913 * r3 = ( -1/3, -sqrt(2) / 3, -sqrt(6) / 3 )
914 * |r0| = |r1| = |r2| = |r3| = 1
915 * Distance between any two points is 2 sqrt(6) / 3
917 * Normals: The unit normals are simply the negative of the coordinates of the point not on the surface.
920 double r0[3] = { 1.0, 0.0, 0.0 } ;
921 double r1[3] = { -0.333333333333, 0.942809041582, 0.0 } ;
922 double r2[3] = { -0.333333333333, -0.471404520791, 0.816496580928 } ;
923 double r3[3] = { -0.333333333333, -0.471404520791, -0.816496580928 } ;
925 glBegin( GL_TRIANGLES ) ;
926 glNormal3d ( -1.0, 0.0, 0.0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r2 ) ;
927 glNormal3d ( 0.333333333333, -0.942809041582, 0.0 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r2 ) ; glVertex3dv ( r3 ) ;
928 glNormal3d ( 0.333333333333, 0.471404520791, -0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r3 ) ; glVertex3dv ( r1 ) ;
929 glNormal3d ( 0.333333333333, 0.471404520791, 0.816496580928 ) ; glVertex3dv ( r0 ) ; glVertex3dv ( r1 ) ; glVertex3dv ( r2 ) ;
936 double icos_r[12][3] = { { 1.0, 0.0, 0.0 },
937 { 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 },
938 { -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 },
939 { -1.0, 0.0, 0.0 } } ;
940 int icos_v [20][3] = { { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 4 }, { 0, 4, 5 }, { 0, 5, 1 },
941 { 1, 8, 2 }, { 2, 7, 3 }, { 3, 6, 4 }, { 4, 10, 5 }, { 5, 9, 1 },
942 { 1, 9, 8 }, { 2, 8, 7 }, { 3, 7, 6 }, { 4, 6, 10 }, { 5, 10, 9 },
943 { 11, 9, 10 }, { 11, 8, 9 }, { 11, 7, 8 }, { 11, 6, 7 }, { 11, 10, 6 } } ;
945 void FGAPIENTRY glutWireIcosahedron( void )
948 for ( i = 0; i < 20; i++ )
951 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] ) ;
952 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] ) ;
953 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] ) ;
954 glBegin ( GL_LINE_LOOP ) ;
955 glNormal3dv ( normal ) ;
956 glVertex3dv ( icos_r[icos_v[i][0]] ) ;
957 glVertex3dv ( icos_r[icos_v[i][1]] ) ;
958 glVertex3dv ( icos_r[icos_v[i][2]] ) ;
966 void FGAPIENTRY glutSolidIcosahedron( void )
970 glBegin ( GL_TRIANGLES ) ;
971 for ( i = 0; i < 20; i++ )
974 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] ) ;
975 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] ) ;
976 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] ) ;
977 glNormal3dv ( normal ) ;
978 glVertex3dv ( icos_r[icos_v[i][0]] ) ;
979 glVertex3dv ( icos_r[icos_v[i][1]] ) ;
980 glVertex3dv ( icos_r[icos_v[i][2]] ) ;
989 double rdod_r[14][3] = { { 0.0, 0.0, 1.0 },
990 { 0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, 0.707106781187, 0.5 }, { -0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, -0.707106781187, 0.5 },
991 { 0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, -0.707106781187, 0.0 }, { 0.707106781187, -0.707106781187, 0.0 },
992 { 0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, 0.707106781187, -0.5 }, { -0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, -0.707106781187, -0.5 },
993 { 0.0, 0.0, -1.0 } } ;
994 int rdod_v [12][4] = { { 0, 1, 5, 2 }, { 0, 2, 6, 3 }, { 0, 3, 7, 4 }, { 0, 4, 8, 1 },
995 { 5, 10, 6, 2 }, { 6, 11, 7, 3 }, { 7, 12, 8, 4 }, { 8, 9, 5, 1 },
996 { 5, 9, 13, 10 }, { 6, 10, 13, 11 }, { 7, 11, 13, 12 }, { 8, 12, 13, 9 } } ;
997 double rdod_n[12][3] = {
998 { 0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, -0.353553390594, 0.5 }, { 0.353553390594, -0.353553390594, 0.5 },
999 { 0.000000000000, 1.000000000000, 0.0 }, { -1.000000000000, 0.000000000000, 0.0 }, { 0.000000000000, -1.000000000000, 0.0 }, { 1.000000000000, 0.000000000000, 0.0 },
1000 { 0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, -0.353553390594, -0.5 }, { 0.353553390594, -0.353553390594, -0.5 }
1003 void FGAPIENTRY glutWireRhombicDodecahedron( void )
1006 for ( i = 0; i < 12; i++ )
1008 glBegin ( GL_LINE_LOOP ) ;
1009 glNormal3dv ( rdod_n[i] ) ;
1010 glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
1011 glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
1012 glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
1013 glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
1021 void FGAPIENTRY glutSolidRhombicDodecahedron( void )
1025 glBegin ( GL_QUADS ) ;
1026 for ( i = 0; i < 12; i++ )
1028 glNormal3dv ( rdod_n[i] ) ;
1029 glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
1030 glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
1031 glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
1032 glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
1040 static GLdouble tetrahedron_v[4][3] = /* Vertices */
1042 { -0.5, -0.288675134595, -0.144337567297 },
1043 { 0.5, -0.288675134595, -0.144337567297 },
1044 { 0.0, 0.577350269189, -0.144337567297 },
1045 { 0.0, 0.0, 0.672159013631 }
1048 static GLint tetrahedron_i[4][3] = /* Vertex indices */
1050 { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 }
1053 static GLdouble tetrahedron_n[4][3] = /* Normals */
1056 { -0.816496580928, 0.471404520791, 0.333333333333 },
1057 { 0.0, -0.942809041582, 0.333333333333 },
1058 { 0.816496580928, 0.471404520791, 0.333333333333 }
1061 void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
1065 if ( num_levels == 0 )
1068 for ( i = 0 ; i < NUM_FACES ; i++ )
1070 glBegin ( GL_LINE_LOOP ) ;
1071 glNormal3dv ( tetrahedron_n[i] ) ;
1072 for ( j = 0; j < 3; j++ )
1074 double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
1075 double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
1076 double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
1077 glVertex3d ( x, y, z ) ;
1085 GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
1088 local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
1089 local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
1090 local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
1091 glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
1092 local_offset[0] += scale ;
1093 glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
1094 local_offset[0] -= 0.5 * scale ;
1095 local_offset[1] += 0.866025403784 * scale ;
1096 glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
1097 local_offset[1] -= 0.577350269189 * scale ;
1098 local_offset[2] += 0.816496580928 * scale ;
1099 glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
1103 void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
1107 if ( num_levels == 0 )
1109 glBegin ( GL_TRIANGLES ) ;
1111 for ( i = 0 ; i < NUM_FACES ; i++ )
1113 glNormal3dv ( tetrahedron_n[i] ) ;
1114 for ( j = 0; j < 3; j++ )
1116 double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
1117 double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
1118 double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
1119 glVertex3d ( x, y, z ) ;
1127 GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
1130 local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
1131 local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
1132 local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
1133 glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
1134 local_offset[0] += scale ;
1135 glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
1136 local_offset[0] -= 0.5 * scale ;
1137 local_offset[1] += 0.866025403784 * scale ;
1138 glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
1139 local_offset[1] -= 0.577350269189 * scale ;
1140 local_offset[2] += 0.816496580928 * scale ;
1141 glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
1147 /*** END OF FILE ***/