/* I donŐt remember where I originally got the algorithm. Somewhere in Dr. DobbŐs Journal Possibilities include: Dick Oliver, Fractals in the Real World, DDJ April 1991 Steven Janke, Recursive Images, DDJ July 1991 */ #declare PAINT = 1; #declare DRAW = 0; #declare BLOBPAINT = 2; #macro fractics_paint(center,aSphere,dotcount,children,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #local dummy = 0; #local blobStrength = 0; fractics(PAINT,center,aSphere,dotcount,children,dummy,dummy,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #end #macro fractics_paint_blob(center,bStrength,bRadius,dotcount,children,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #local dummy = 0; #local blobStrength = 0; fractics(BLOBPAINT,center,bRadius,dotcount,children,bStrength,dummy,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #end #macro fractics_draw(center,theLineWidth,levelcount,levelmaterials,children,object_points,object_lines,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #local dummy = 0; #local blobStrength = 0; fractics(DRAW,center,theLineWidth,levelcount,children,object_points,object_lines,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #end #macro fractics_draw_blob(center,theLineWidth,levelcount,blobStrength,levelmaterials,children,object_points,object_lines,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #local dummy = 0; fractics(DRAW,center,theLineWidth,levelcount,children,object_points,object_lines,squaresizes,squarespins,squaremoves,squareweights,minBound,maxBound) #end //how_draw: PAINT if paint, DRAW if draw //CENTER: center of fractal //theShape: either an object (for painting) or a radius percentage (for drawing) //pointSize: radius of sphere that does the points //dotlevels: number of dots or number of levels //ntrans = number of transformations, that is, number of children //npoints = number of points in the seed object //seedpoints = two-d array of x,y points in seed object //sizes = two-d array of size reduction per level for x(0) and y (1), one for each child //spins = degrees change each level: two-d array of spins for x (0) and y (1), one for each child //moves = two-d array of moves each level for x(0) and y (1), one for each child //weights = array of weights, one per child //minimum and maximumBound = limit of fractal in drawing #macro fractics(how_draw,CENTER,theShape,dotlevels,ntrans,npoints,seedpoints,sizes,spins,moves,weights,minimumBound,maximumBound) #local coeffs= array[ntrans][4] #local Mass=0; #local StA = 1; #local StB = 0; #local StC = 0; #local StD = 1; //generate coefficients of transformation equation? #local c_t = 0; #while (c_t < ntrans) #declare coeffs[c_t][0] = sizes[c_t][0] * cos(radians(spins[c_t][0])); #declare coeffs[c_t][1] = -sizes[c_t][1] * sin(radians(spins[c_t][1])); #declare coeffs[c_t][2] = sizes[c_t][0] * sin(radians(spins[c_t][0])); #declare coeffs[c_t][3] = sizes[c_t][1] * cos(radians(spins[c_t][1])); #declare Mass = Mass + weights[c_t]; #declare c_t = c_t + 1; #end #switch (how_draw) #case (DRAW) /* draw by line */ //seed is apparently the actual seed shape fractics_draw_engine(StA,StB,StC,StD, CENTER.x,CENTER.y,dotlevels) /*draw and rotate shapes */ #break; #case (PAINT) /* draw by random dots */ fractics_paint_engine(dotlevels,dummy,dummy) /* paint dots */ #break; #case (BLOBPAINT) /* draw with blobs */ fractics_paint_engine(dotlevels,theShape,npoints) /* paint blobs */ #end #end //ndots = number of dots to draw //blobStrength = strength of blob spheres //blobRadius = radius of blob spheres #macro fractics_paint_engine(ndots,blobStrength,blobRadius) #local mx = CENTER.x; #local my = CENTER.y; #local mz = CENTER.z; #ifndef (R1) #local R1 = seed(1); #end /* Counter for number of dots painted so far */ #local ct = 0; /* current and next dot */ #local x1 = 0.0; #local y1 = 0.0; /* Keep going until we reach the ndots limit */ #while (ct 8) #if (nx < maximumBound.x & nx > minimumBound.x & ny < maximumBound.y & ny > minimumBound.y) #if (blobStrength = 0 | blobRadius = 0) object { theShape translate } #else sphere { <0,0,0>, blobRadius,blobStrength translate } #end #end #end #declare ct = ct + 1; #end #end /* This recursive routine draws one "parent" polygon, then calls iteself to draw the "children" using the transformations defined above Currently, this routine ignores weights, but it may be added via grey scale, later. We'll see how necessary it is */ #macro fractics_draw_engine(a,b,c,d,mx,my,iter) #local mz = CENTER.z; // Point on the parent: x1,y1 // Points on the child: p, x2,y2 #local x2 = array[npoints] #local y2 = array[npoints] #local cp = 0; #while (cp < npoints) #local x1 = seedpoints[cp][0]; #local y1 = seedpoints[cp][1]; #declare x2[cp] = a * x1 + b * y1 + mx; #declare y2[cp] = c * x1 + d * y1 + my; #declare cp = cp + 1; #end // Now draw the new polygon on the screen #local lastPoint = ; #declare cp = 0; #local thisPoint = <0,0,0>; #while (cp; #if (theShape > 0) #local lineWidth = vlength(thisPoint-lastPoint)*theShape; #else #local lineWidth = abs(theShape); #end cylinder { #local thiscolor = dotlevels - iter; #if (blobStrength = 0) lastPoint,thisPoint,lineWidth #if (dimensions(levelmaterials) = 1 & dimension_size(levelmaterials,1) > thiscolor) material { levelmaterials[thiscolor] } #end #else lastPoint,thisPoint,lineWidth, blobStrength #if (dimensions(levelmaterials) = 1 & dimension_size(levelmaterials,1) > thiscolor) texture { levelmaterials[thiscolor] } #end #end } #declare lastPoint = thisPoint; #declare cp = cp + 1; #end #if (iter>1) /* If we're at the deepest level, back out */ /* Do a recursive call for each "child" of the polygon we just drew */ #local ct = 0; #while (ct < ntrans) fractics_draw_engine(coeffs[ct][0] * a + coeffs[ct][2] * b, coeffs[ct][1] * a + coeffs[ct][3] * b, coeffs[ct][0] * c + coeffs[ct][2] * d, coeffs[ct][1] * c + coeffs[ct][3] * d, moves[ct][0] * a + moves[ct][1] * b + mx, moves[ct][0] * c + moves[ct][1] * d + my, iter-1) #declare ct = ct + 1; #end #end #end