Name: Richard Kline Filename: "sgasket.jpg" Programs Used: POVRay 2.2 for rendering and ImageMagick for postprocessing "sgasket.jpg" is a file displaying Sierpinski's gasket in different ways. Sierpinski's gasket was discovered by W. Sierpinski around World War I. It is generated by dividing a triangle into four congruent smaller triangles, doing the same to each of them and iterating infinitely (thanks to xfractint for the history). The representations shown here use equilateral triangles and have three triangles formed by each subdivision which point the same way solid and the fourth triangle open. The image has a two different three dimensional representations of the gasket (with only a finite number of subdivisions of the triangles). The first shows the triangles as pyramids (squashed tetrahedra) with the pyramids generated by subdivision stacked above the pyramids for the previous generation. 7 generations are shown, each with a different texture ( the 4th through 7th are solid colors because the individual pyramids are so small). The second is a tetrahedron whose sides have been subdivided 4 times (equivalent to the fifth layer in the stack of pyramids) times. The tetrahedron has been arranged to throw a cool shadow on the floor. In the upper right of the scene is a spherical mirror to better show the arrangement of the layers of pyramids. After rendering with POVRay 2.2, I applied a gamma correction of 1.2 with ImageMagick since the lower layers of the pyramid were a bit too dark. I didn't write down the rendering time of the final version on my 486-DX2 66 running Linux, but it was about 2-3 hours I think. Enclosed is the overall scene file (light sources background etc), some of the include files, and the recursive C program which generated the include files used. The include files I used are over 0.5 Megabytes and are not included. I didn't find the time to neaten them up as much as I would like for public consumption. Sorry. Richard Kline rkline@cais.com /* Begin file gasket.pov the overall scene file for the sierpinski's gasket */ // POVRay for a 3-D Sierpinski's Gasket // #include "colors.inc" #include "shapes.inc" #include "shapes2.inc" #include "textures.inc" #include "stones.inc" /* Include the file with all the texture decalarations for the levels of the pyramid representation */ #include "level.inc" /* Include the declaration for the planar triangle representation */ #include "tg5.inc" /* Include the different layers for the pyramid representation (It was done this way to allow different layers to be switched on and off during testing) */ #include "l1.inc" #include "l2.inc" #include "l3.inc" #include "l4.inc" #include "l5.inc" #include "l6.inc" #include "l7.inc" camera { location <0.0, 30.0, -200.0> direction <0.0, -0.15, 1> up <0.0, 1.0, 0.0> right <4/3, 0.0, 0.0> rotate <55,-90,0> translate < 1.25*64, 0, 0.65*128*.28868> } /* Declare the spherical mirror (actually a tetrahedron with one spherical side ). */ #declare Sphetrahedron = intersection {sphere {<0,79,0>, 80 } plane {-z,1 rotate <19.47, 0, 0> } plane {-z,1 rotate <19.47, -120, 0> } plane {-z,1 rotate <19.47, 120, 0> } } /* Declare the tetrahedron with Sierpinski's gasket sides the odd 1.325 and .94 values in the translate commands were neede to make the edges join I must have a slight error in the values in the C program generating the file which declares Striangle */ #declare Stetrahedron = union { object {Striangle translate <0,-26.12778*1.325,0> rotate <0,60,0> } object {Striangle rotate <90,0,0> rotate <19.4667,0,0> translate <0,0,-26.12778*.94> } object {Striangle rotate <90,0,0> rotate <19.4667,0,0> translate <0,0,-26.12778*.94> rotate <0,-120,0> } object {Striangle rotate <90,0,0> rotate <19.4667,0,0> translate <0,0,-26.12778*.94> rotate <0,120,0> } scale 0.55 pigment {color rgb <0.2,1,0.25>} } plane { y, -50.0 pigment { checker colour rgb<0.2,0.2,1> colour Gray quick_color Blue scale 40.0 } finish { crand 0.01 ambient 0.3 diffuse 0.7 reflection 0.1 brilliance 3.0 } } plane { y, 500.0 pigment { Bright_Blue_Sky quick_colour red 0.5 green 0.5 blue 0.8 scale <2000.0, 500.0, 1000.0> } finish { crand 0.05 ambient 0.7 diffuse 0.0 } } /* Place the spherical mirror */ object {Sphetrahedron scale 40 rotate <-110,0,0> rotate <0,125,0> translate <-64,-10,136> pigment { White } finish { ambient 0.05 diffuse 0.1 reflection 0.8 brilliance 4.0 } } object {Stetrahedron rotate <0,30,0> rotate <-185.516,0,17> translate <116,0,-40> translate <-8.6385, 30, -2.89711>} light_source { <60.0, 300.0, -45.0> colour White rotate<0,30,0>} light_source { <0.0, 70.0, -200.0> colour White rotate <0,60,0>} light_source { <1200,50,800> color Gray80} /* End file gasket.pov */ /* Begin file level.inc Include file for textures */ #declare Level1 = texture {Jade scale 12} #declare Level2 = texture {Red_Marble scale 10} #declare Level3 = texture {Blue_Agate scale 10} #declare Level4 = texture {pigment {Green filter 0.000000 }} #declare Level5 = texture {pigment {Red filter 0.000000 }} #declare Level6 = texture {pigment {Blue} } #declare Level7 = texture {pigment {Green} } #declare Level8 = texture {pigment {Green} } #declare Level9 = texture {pigment {Green} } /* end file level.inc */ /* Begin file l1.inc First level of pyramid representation */ // nmax = 1 // Sierpinski's Gasket POVRAY 2.2 file generated by gask.c union { // n=1 scale=128.000000 triangle { < 0.00000, -40.00000, -73.90080>, < -64.00000, -40.00000, 36.95104>, < 64.00000, -40.00000, 36.95104> } triangle { < 0.00000, -8.00000, 0.00000>, < -64.00000, -40.00000, 36.95104>, < 64.00000, -40.00000, 36.95104> } triangle { < 0.00000, -40.00000, -73.90080>, < 0.00000, -8.00000, 0.00000>, < 64.00000, -40.00000, 36.95104> } triangle { < 0.00000, -40.00000, -73.90080>, < -64.00000, -40.00000, 36.95104>, < 0.00000, -8.00000, 0.00000> } texture {Level1} } /* End file l1.inc */ /* Begin file tg2.inc (smaller version (1 subdivision of the triangle instead of 4) of the file tg5.inc) with declaration for a planar Sierpinski's gasket */ // nmax = 2 // Sierpinski's Gasket POVRAY 2.2 file generated by gask.c #declare Striangle = union { // n=2 scale=64.000000 triangle { < 0.00000, 0.00000, -73.90080>, < -32.00000, 0.00000, -18.47488>, < 32.00000, 0.00000, -18.47488> } // n=2 scale=64.000000 triangle { < -32.00000, 0.00000, -18.47488>, < -64.00000, 0.00000, 36.95104>, < 0.00000, 0.00000, 36.95104> } // n=2 scale=64.000000 triangle { < 32.00000, 0.00000, -18.47488>, < 0.00000, 0.00000, 36.95104>, < 64.00000, 0.00000, 36.95104> } } /* End file tg2.inc */ /* Begin file sgask.c Recursive C program to generate Sierpinski's gasket POV include files */ #include #include #include #include float vu[3][3],off[3]; void sierp( float vu[3][3], float off[3], float centx, float centy, float centz, int n, int nmax, int pflag); /* Program gask.c outputs POVRay 2.2 instructions for Sierpinski's gasket figures onto standard output Usage ( in Unix): sgask n > file.inc If n is positive, sgask will output a POV include file containing triangle commands for a layer of pyramids whose bases form the sierpinski gasket created by bisecting the sides of an equilateral triangle n-1 times using the texture "Level"n. The bases of the individual pyramids will have a side length of 128/(2^(n-1)) and the layer as a whole will have a side length of 128. If n is negative, sgask will output a POV include file which declares the object Striangle to be the triangles only (not pyramids) for a sierpinski gasket created by bisecting the sides of an equilateral triangle n-1 times. The individual triangles will have side lengths of 128/(2^(n-1)) and the object as a whole will have a side length of 128. With no arguments, sgask defaults to n=+3 */ main (int argc, char *argv[]) { float centx,centy,centz; int n,nmax,pflag; /* Define the vertices for an equilateral triangle with side length 1 in the x-z plane */ vu[0][0] = 0.; vu[0][1] = 0.; vu[0][2] = -0.57735; vu[1][0] = -0.5; vu[1][1] = 0.; vu[1][2] = 0.28868; vu[2][0] = 0.5; vu[2][1] = 0.; vu[2][2] = 0.28868; centx = 0.; centy = -40.; centz = 0.; /* offsets for each layer is the program is called with a positive argument chosen to place each layer above and with the edge directly over the outer most apexes of the previous layer */ off [0]= 0.5; off [1]= 1.; off [2]= 0.5; n = 1; nmax = 3; pflag = 1; if ( argc > 1 ) { nmax = atoi ( argv[1]); if ( nmax < 0) { nmax = -nmax; pflag = 0; printf ("// nmax = %d\n", nmax); centy = 0; } if ( nmax > 0 && nmax <9 ) { printf ("// Sierpinski's Gasket POVRAY 2.2 file generated by gask.c \n\n\n"); if (pflag == 0) { printf ("#declare Striangle = union { \n"); sierp ( vu, off, centx, centy, centz, n, nmax, pflag); printf (" }\n"); } else { printf ("union { \n"); sierp ( vu, off, centx, centy, centz, n, nmax, pflag); printf (" texture {Level%d} }\n",nmax); } } } } void sierp( float vu[3][3], float off[3], float cx, float cy, float cz, int n, int nmax, int pflag) { int i; float vx[3],vy[3],vz[3],scale,peaky,xoff,yoff,zoff,filt; scale = 256./pow(2.,n); for (i=0; i<3; i++) { vx[i]= cx+scale*vu[i][0]; vy[i]= cy+scale*vu[i][1]; vz[i]= cz+scale*vu[i][2]; } xoff = off[0]*vu[2][0]*scale*pflag; yoff = off[1]*scale/4.*pflag; zoff = off[2]*vu[2][2]*scale*pflag; peaky = cy+yoff; if (n == nmax) { printf ("\n// n=%d scale=%f\n",n,scale); printf ("triangle { "); for ( i=0; i<3; i++) { printf (" < %7.5f, %7.5f, %7.5f>",vx[i],vy[i],vz[i]); ( i==2) ? printf (" }\n") : printf (","); } if ( pflag == 1) { printf ("triangle { "); for ( i=0; i<3; i++) { if ( i == 0 ) { printf (" < %7.5f, %7.5f, %7.5f>",cx,peaky,cz); } else { printf (" < %7.5f, %7.5f, %7.5f>",vx[i],vy[i],vz[i]); } ( i==2) ? printf (" }\n") : printf (","); } printf ("triangle { "); for ( i=0; i<3; i++) { if ( i == 1 ) { printf (" < %7.5f, %7.5f, %7.5f>",cx,peaky,cz); } else { printf (" < %7.5f, %7.5f, %7.5f>",vx[i],vy[i],vz[i]); } ( i==2) ? printf (" }\n") : printf (","); } printf ("triangle { "); for ( i=0; i<3; i++) { if ( i == 2 ) { printf (" < %7.5f, %7.5f, %7.5f>",cx,peaky,cz); } else { printf (" < %7.5f, %7.5f, %7.5f>",vx[i],vy[i],vz[i]); } ( i==2) ? printf (" }\n") : printf (","); } } } if ( n < nmax ) { for (i=0; i<3; i++) { sierp ( vu, off, cx+scale*vu[i][0]/2.+xoff, cy+scale*vu[i][1]/2.+yoff, cz+scale*vu[i][2]/2.+zoff, n+1, nmax, pflag); } } } /* End file gask.c */