+/*
+ *
+ */
+double rdod_r[14][3] = { { 0.0, 0.0, 1.0 },
+ { 0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, 0.707106781187, 0.5 }, { -0.707106781187, 0.000000000000, 0.5 }, { 0.000000000000, -0.707106781187, 0.5 },
+ { 0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, 0.707106781187, 0.0 }, { -0.707106781187, -0.707106781187, 0.0 }, { 0.707106781187, -0.707106781187, 0.0 },
+ { 0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, 0.707106781187, -0.5 }, { -0.707106781187, 0.000000000000, -0.5 }, { 0.000000000000, -0.707106781187, -0.5 },
+ { 0.0, 0.0, -1.0 } } ;
+int rdod_v [12][4] = { { 0, 1, 5, 2 }, { 0, 2, 6, 3 }, { 0, 3, 7, 4 }, { 0, 4, 8, 1 },
+ { 5, 10, 6, 2 }, { 6, 11, 7, 3 }, { 7, 12, 8, 4 }, { 8, 9, 5, 1 },
+ { 5, 9, 13, 10 }, { 6, 10, 13, 11 }, { 7, 11, 13, 12 }, { 8, 12, 13, 9 } } ;
+double rdod_n[12][3] = {
+ { 0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, 0.353553390594, 0.5 }, { -0.353553390594, -0.353553390594, 0.5 }, { 0.353553390594, -0.353553390594, 0.5 },
+ { 0.000000000000, 1.000000000000, 0.0 }, { -1.000000000000, 0.000000000000, 0.0 }, { 0.000000000000, -1.000000000000, 0.0 }, { 1.000000000000, 0.000000000000, 0.0 },
+ { 0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, 0.353553390594, -0.5 }, { -0.353553390594, -0.353553390594, -0.5 }, { 0.353553390594, -0.353553390594, -0.5 }
+ } ;
+
+void FGAPIENTRY glutWireRhombicDodecahedron( void )
+{
+ int i ;
+ for ( i = 0; i < 12; i++ )
+ {
+ glBegin ( GL_LINE_LOOP ) ;
+ glNormal3dv ( rdod_n[i] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
+ glEnd () ;
+ }
+}
+
+/*
+ *
+ */
+void FGAPIENTRY glutSolidRhombicDodecahedron( void )
+{
+ int i ;
+
+ glBegin ( GL_QUADS ) ;
+ for ( i = 0; i < 12; i++ )
+ {
+ glNormal3dv ( rdod_n[i] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][0]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][1]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][2]] ) ;
+ glVertex3dv ( rdod_r[rdod_v[i][3]] ) ;
+ }
+
+ glEnd () ;
+}
+
+#define NUM_FACES 4
+
+static GLdouble tetrahedron_v[4][3] = /* Vertices */
+{
+ { -0.5, -0.288675134595, -0.144337567297 },
+ { 0.5, -0.288675134595, -0.144337567297 },
+ { 0.0, 0.577350269189, -0.144337567297 },
+ { 0.0, 0.0, 0.672159013631 }
+} ;
+
+static GLint tetrahedron_i[4][3] = /* Vertex indices */
+{
+ { 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 }
+} ;
+
+static GLdouble tetrahedron_n[4][3] = /* Normals */
+{
+ { 0.0, 0.0, -1.0 },
+ { -0.816496580928, 0.471404520791, 0.333333333333 },
+ { 0.0, -0.942809041582, 0.333333333333 },
+ { 0.816496580928, 0.471404520791, 0.333333333333 }
+} ;
+
+void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
+{
+ int i, j ;
+
+ if ( num_levels == 0 )
+ {
+
+ for ( i = 0 ; i < NUM_FACES ; i++ )
+ {
+ glBegin ( GL_LINE_LOOP ) ;
+ glNormal3dv ( tetrahedron_n[i] ) ;
+ for ( j = 0; j < 3; j++ )
+ {
+ double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
+ double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
+ double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
+ glVertex3d ( x, y, z ) ;
+ }
+
+ glEnd () ;
+ }
+ }
+ else
+ {
+ GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
+ num_levels -- ;
+ scale /= 2.0 ;
+ local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
+ local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
+ local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
+ glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[0] += scale ;
+ glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[0] -= 0.5 * scale ;
+ local_offset[1] += 0.866025403784 * scale ;
+ glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[1] -= 0.577350269189 * scale ;
+ local_offset[2] += 0.816496580928 * scale ;
+ glutWireSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ }
+}
+
+void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale )
+{
+ int i, j ;
+
+ if ( num_levels == 0 )
+ {
+ glBegin ( GL_TRIANGLES ) ;
+
+ for ( i = 0 ; i < NUM_FACES ; i++ )
+ {
+ glNormal3dv ( tetrahedron_n[i] ) ;
+ for ( j = 0; j < 3; j++ )
+ {
+ double x = offset[0] + scale * tetrahedron_v[tetrahedron_i[i][j]][0] ;
+ double y = offset[1] + scale * tetrahedron_v[tetrahedron_i[i][j]][1] ;
+ double z = offset[2] + scale * tetrahedron_v[tetrahedron_i[i][j]][2] ;
+ glVertex3d ( x, y, z ) ;
+ }
+ }
+
+ glEnd () ;
+ }
+ else
+ {
+ GLdouble local_offset[3] ; /* Use a local variable to avoid buildup of roundoff errors */
+ num_levels -- ;
+ scale /= 2.0 ;
+ local_offset[0] = offset[0] + scale * tetrahedron_v[0][0] ;
+ local_offset[1] = offset[1] + scale * tetrahedron_v[0][1] ;
+ local_offset[2] = offset[2] + scale * tetrahedron_v[0][2] ;
+ glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[0] += scale ;
+ glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[0] -= 0.5 * scale ;
+ local_offset[1] += 0.866025403784 * scale ;
+ glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ local_offset[1] -= 0.577350269189 * scale ;
+ local_offset[2] += 0.816496580928 * scale ;
+ glutSolidSierpinskiSponge ( num_levels, local_offset, scale ) ;
+ }
+}
+
+#undef NUM_FACES
+