// IFS Fern based on Paul Bourke's C source. // http://www.mhri.edu.au/~pdb/fractals/fern/ // Ported, modified and commented by Anders Haglund. // andershaglund@hotmail.com // // Rendering time with n = 10000 (on a pentium-166 mmx and pov-ray for windows) // Parsing: 41 seconds // Rendering: 4 seconds // // This scene is made for Pov-Ray 3.0. // // The general form of the series are: // x = a x + b yn + c // (n+1) n // y = d x + e yn + f // (n+1) n // // The Fern is made by randomizing the (a,b,c,d,e,f) set between 4 diffrent // sets: // set1 set2 set3 set4 // a 0.0 0.2 -0.15 0.75 // b 0.0 -0.26 0.28 0.04 // c 0.0 0.23 0.26 -0.04 // d 0.16 0.22 0.24 0.85 // e 0.0 0.0 0.0 0.0 // f 0.0 1.6 0.44 1.6 // p 0.1 0.08 0.08 0.74 // (p is the probability for that set to occur) // // To do: // * Convert to Pov-Ray 3.1 (much nicer code with arrays) // * True 3D. Anyone got the IFS sets for a 3D Fern? Please e-mail me. camera { location <0,0,-5> look_at <0,0,0> } light_source { <0,0,-5> color rgb <1,1,1> } #declare n = 10000 ;// Number of spheres // Box to map IFS in to, used for scaling the IFS #declare nx = 4 ; #declare ny = 4 ; #declare r1 = seed(0) ;// Random seed for IFS #declare sphereradius = 0.02; // Radius of spheres, should get // smaler when n get bigger. // Don't modify these: // For finding bounding box of IFS (used for scaling and centering) #declare xmin = 1000000 ; #declare xmax = -1000000 ; #declare ymin = xmin ; #declare ymax = xmax ; union { #declare j = 0; #while (j < 2) // Loop twise, first time to find xmax,xmin,ymax and ymin, // second time to create the spheres // Start position (doesn't matter because the IFS is always centered) #declare xlast = 0 ; #declare ylast = 0 ; #if (j = 1) #declare s = min(nx/(xmax-xmin),ny/(ymax-ymin)) ;// Calculate scaling // Calculate centering #declare xmid = (xmin+xmax)/2 ; #declare ymid = (ymin+ymax)/2 ; #end #declare i = 0 ; #while (i < n) // Loop once for every sphere // Find wich set to use #declare r = rand(r1); #if (r < 0.1) #declare a = 0 ; #declare b = 0 ; #declare c = 0 ; #declare d = 0.16 ; #declare e = 0 ; #declare f = 0 ; #end #if (r >= 0.1 & r < 0.18) #declare a = 0.2 ; #declare b = -0.26 ; #declare c = 0.23 ; #declare d = 0.22 ; #declare e = 0 ; #declare f = 1.6 ; #end #if (r >= 0.18 & r < 0.26) #declare a = -0.15 ; #declare b = 0.28 ; #declare c = 0.26 ; #declare d = 0.24 ; #declare e = 0 ; #declare f = 0.44 ; #end #if (r >= 0.26) #declare a = 0.75 ; #declare b = 0.04 ; #declare c = -0.04; #declare d = 0.85; #declare e = 0; #declare f = 1.6; #end // Calculate new coordinate #declare px = a*xlast+b*ylast+e; #declare py = c*xlast+d*ylast+f; #if (j = 0) // First loop to find bounding box #if (px < xmin) #declare xmin = px; #end #if (px > xmax) #declare xmax = px; #end #if (py < ymin) #declare ymin = py; #end #if (py > ymax) #declare ymax = py; #end #else // Second loop to create the spheres // Scale and center the IFS #declare ix = (px - xmid)*s ; #declare iy = (py - ymid)*s ; // Create the sphere! sphere { ,sphereradius pigment { color rgb } } #end // Save coordinate for next loop #declare xlast = px ; #declare ylast = py ; #declare i = i+1; #end #declare j = j+1; #end }