snowflake3d.c
/* Given an equilateral triangle T with vertices at v0, v1, v2, 
 * places an equilateral tetrahedron with its base on the subtriangle
 * T' of T whose vertices are at the midpoints of the edges of T.
 * T' itself is not drawn again. So a total of 6 new triangles are
 * drawn: 3 subtriangles of T and 3 faces of the the tetrahedron.
 * The "length" variable stores the current side length of T.
 */
Given an equilateral triangle T with vertices at v0, v1, v2,
places an equilateral tetrahedron with its base on the subtriangle
T' of T whose vertices are at the midpoints of the edges of T.
T' itself is not drawn again. So a total of 6 new triangles are
drawn: 3 subtriangles of T and 3 faces of the the tetrahedron.
The "length" variable stores the current side length of T.
Given an equilateral triangle T with vertices at v0 v1 v2 places an equilateral tetrahedron with its base on the subtriangle T ' of T whose vertices are at the midpoints of the edges of T . T ' itself is not drawn again . So a total of 6 new triangles are drawn : 3 subtriangles of T and 3 faces of the the tetrahedron . The " length " variable stores the current side length of T .
void addtetra(float* v0, float* v1, float* v2, int depth, float length){
  GLfloat v3[3], v4[3], v5[3], v6[3], 
          vec1[3], vec2[3], vecn[3], center[3];
  GLint i;
  if (depth == 0){
      drawtriangle(v0, v1, v2);
      return;
  }
  for(i=0; i < 3; i++){
    v3[i]     = (v0[i] + v1[i])/2.0;
    v4[i]     = (v1[i] + v2[i])/2.0;
    v5[i]     = (v2[i] + v0[i])/2.0;  
    vec1[i]   =  v1[i] - v0[i];
    vec2[i]   =  v2[i] - v0[i];
    center[i] = (v0[i] + v1[i] + v2[i])/3.0;
  }
  crossproduct(vec1, vec2, vecn);
  normalize(vecn);
  for(i=0; i < 3; i++){
    v6[i] = center[i] + (length/2.0) * (ROOT2/ROOT3)* vecn[i];
      }
  addtetra(v0, v3, v5, depth-1, length/2.0);
  addtetra(v3, v1, v4, depth-1, length/2.0);
  addtetra(v4, v2, v5, depth-1, length/2.0);
  addtetra(v4, v5, v6, depth-1, length/2.0);
  addtetra(v3, v6, v5, depth-1, length/2.0);
  addtetra(v4, v6, v3, depth-1, length/2.0);
}
void addtetra ( float * v0 , float * v1 , float * v2 , int depth , float length ) { GLfloat v3 [ 3 ] , v4 [ 3 ] , v5 [ 3 ] , v6 [ 3 ] , vec1 [ 3 ] , vec2 [ 3 ] , vecn [ 3 ] , center [ 3 ] ; GLint i ; if ( depth == 0 ) { drawtriangle ( v0 , v1 , v2 ) ; return ; } for ( i = 0 ; i < 3 ; i ++ ) { v3 [ i ] = ( v0 [ i ] + v1 [ i ] ) / 2.0 ; v4 [ i ] = ( v1 [ i ] + v2 [ i ] ) / 2.0 ; v5 [ i ] = ( v2 [ i ] + v0 [ i ] ) / 2.0 ; vec1 [ i ] = v1 [ i ] - v0 [ i ] ; vec2 [ i ] = v2 [ i ] - v0 [ i ] ; center [ i ] = ( v0 [ i ] + v1 [ i ] + v2 [ i ] ) / 3.0 ; } crossproduct ( vec1 , vec2 , vecn ) ; normalize ( vecn ) ; for ( i = 0 ; i < 3 ; i ++ ) { v6 [ i ] = center [ i ] + ( length / 2.0 ) * ( ROOT2 / ROOT3 ) * vecn [ i ] ; } addtetra ( v0 , v3 , v5 , depth - 1 , length / 2.0 ) ; addtetra ( v3 , v1 , v4 , depth - 1 , length / 2.0 ) ; addtetra ( v4 , v2 , v5 , depth - 1 , length / 2.0 ) ; addtetra ( v4 , v5 , v6 , depth - 1 , length / 2.0 ) ; addtetra ( v3 , v6 , v5 , depth - 1 , length / 2.0 ) ; addtetra ( v4 , v6 , v3 , depth - 1 , length / 2.0 ) ; }
Given an equilateral triangle T with vertices at v0, v1, v2,
 places an equilateral tetrahedron with its base on the subtriangle
 T' of T whose vertices are at the midpoints of the edges of T.
 T' itself is not drawn again.
Given an equilateral triangle T with vertices at v0 v1 v2 places an equilateral tetrahedron with its base on the subtriangle T ' of T whose vertices are at the midpoints of the edges of T . T ' itself is not drawn again .