//Make some interesting recursive shapes, //Made by Spider, spider@bahnhof.se //Distribute freely, but theese lines stay on top of the file. //Version 2.0 //version history: // 1.0 : First release // 1.0a : bug fix, #declare/#local and N = 10. // 2.0 : Added Draw2 wich was the inteded one. // 2.1 : Added purge macro. will empty the list for you, in order to create more instances. Adddded draw3. //----------------HOW-TO /* The FIRST point added will be considered "stem" The rest of the points are branches. The Draw() and Draw2() macros have twwo common values iLevel : How much to recurse through it. fRadii : Radius of the stem the Draw2 macro uses the stem only once, then it takes the last branch and uses as stem. The Draw2 macro will place all branches at the END of the stem. all rotations are in accordance to the stem. All rotations are in POV format (around the axis) */ #debug "Commands are:\n" #debug "AddPoint(point, angle(to base, or to stem), length(in 3D) )\n" #debug "Draw(Level(how many copies),Radii(Radius of cylinder))\n" #debug "bugs/comments: spider@bahnhof.se\n" #debug "To get a textured example, uncummont the pigment in the Draw() macro\n" #ifndef(N) #warning "Max amount of segments(N) not declared, defaulting to 10\n" #declare N = 10; #end //Constants for data. #declare cPoint = 0; #declare cAngle = 1; #declare cLength = 2; //<0,0,0> doesn't work #declare noPoint = <-1.001,-1,-1>; #macro purge() #undef arr #declare arr = array[N][3] #local I = 0; #while(I; #declare arr[I][cLength] = <0.001,0,0>; #local I = I + 1; #end #end //prepare. purge() #macro AddPoint(vPoint,vAngle, vLength) #local I = 0; #local Done = false; #while(Done!=true) #local H = arr[I][cPoint]; #if( (H.x=noPoint.x)& (H.y=noPoint.y)& (H.z=noPoint.z) ) #declare arr[I][cPoint] = vPoint; #declare arr[I][cAngle] = vAngle; #declare arr[I][cLength] = vLength; #local Done = true; #end #local I = I + 1; #if(I=10)//break loop #local Done = true; #end #end #end #macro Draw(iLevel,fRadii) #if(iLevel>0) union { #local I = 0; #while(I, arr[I][cLength], fRadii /* pigment { gradient arr[I][cLength] colour_map { [0 colour rgb <0,0,0> ] [1 colour rgb <2,0,0> ] } #local D = arr[I][cLength]; #if(D.x=0) #local D = D + x; #end #if(D.y=0) #local D = D + y; #end #if(D.z=0) #local D = D + z; #end scale D } */ rotate arr[I][cAngle] translate arr[I][cPoint] #if(I!=0) rotate arr[0][cAngle] #end } #if(iLevel != 1) object { Draw(iLevel-1,fRadii) translate arr[I][cLength] rotate arr[I][cAngle] translate arr[I][cPoint] #if(I!=0) rotate arr[0][cAngle] #end } #end //End level-check #end //End is object check #local I = I + 1; #end } #end #end //Draw according to the stem. //this is what I was after in the beginning. //This will place a stem, as the first point added //The second -> will be branches. //The branches will then be recursively added to eachother //All rotations on the branches are in accordance to the stem. //don't call this directly, it assumes iit is hooked to a "stem" #macro Draw2__________Branches(iLevel,fRadii,fScale) #if(iLevel>0) union { #local I = 1; #while(I,arr[I][cLength],fRadii rotate arr[I][cAngle] } #if(iLevel!=1) object { Draw2__________Branches(iLevel-1,fRadii,fScale) translate arr[I][cLength] rotate arr[I][cAngle] translate arr[I][cPoint] } #end //End level-check #end //End is object check #local I = I + 1; #end //End Loop scale fScale } //End union #end //End If Level #end #macro Draw2(iLevel,fRadii,fScale) //Packager macro. Didn't find any better way. union { cylinder{<0,0,0>,arr[0][cLength],fRadii} object { Draw2__________Branches(iLevel-1,fRadii,fScale) translate arr[0][cLength] } rotate arr[0][cAngle] translate arr[0][cPoint] } #end //Draw2, but modified for this scene... #macro Draw3__________Branches(iLevel,fRadii,fScale, cStart, cEnd, iMaxLevel) #if(iLevel>0) union { #local I = 1; #while(I,arr[I][cLength],fRadii rotate arr[I][cAngle] pigment{ gradient arr[I][cLength] colour_map{ [0 colour cStart] [1 colour rgb (cEnd/iMaxLevel)*iLevel] } } } #if(iLevel!=1) object { Draw3__________Branches(iLevel-1,fRadii,fScale,(cEnd/iMaxLevel)*iLevel,cEnd,iMaxLevel) translate arr[I][cLength] rotate arr[I][cAngle] translate arr[I][cPoint] } #end //End level-check #end //End is object check #local I = I + 1; #end //End Loop scale fScale } //End union #end //End If Level #end #macro Draw3(iLevel,fRadii,fScale, cStart, cEnd) //Packager macro. Didn't find any better way. union { cylinder{<0,0,0>,arr[0][cLength],fRadii pigment{ gradient arr[0][cLength] colour_map{ [0 colour cStart] [1 colour rgb (cEnd/iLevel)*iLevel] } } } object { Draw3__________Branches(iLevel-1, fRadii, fScale, cEnd/iLevel*iLevel, cEnd, iLevel) translate arr[0][cLength] } rotate arr[0][cAngle] translate arr[0][cPoint] } #end