//give 0 if not parallel, 1 if parallel, -1 if anti-parallel #macro t_parallel(V1i,V2i) #local V1=vnormalize(V1i+<0,0,0>); #local V2=vnormalize(V2i+<0,0,0>); #local Vt=(vlength(V1+V2)-1); #if(Vt=1|Vt=-1) Vt #else 0 #end #end //John VanSickle's Reorient macro #macro Reorient(Axis1,Axis2) #local vX1=vnormalize(Axis1); #local vX2=vnormalize(Axis2); #local vY=vnormalize(vcross(vX1,vX2)); #local vZ1=vnormalize(vcross(vX1,vY)); #local vZ2=vnormalize(vcross(vX2,vY)); matrix < vX1.x, vY.x,vZ1.x, vX1.y,vY.y,vZ1.y, vX1.z,vY.z, vZ1.z, 0,0,0 > matrix < vX2.x,vX2.y,vX2.z, vY.x,vY.y, vY.z, vZ2.x,vZ2.y,vZ2.z, 0,0,0 > #end //Vector equivalent of the same (thanks, Ron) #macro v_reorient(V,RefA,RefB) #if((t_parallel(RefA,RefB))=0) #local nA = vnormalize(RefA); #local nB = vnormalize(RefB); #local Axis = vcross(nA,nB); #local Angle = degrees(atan2(vlength(Axis),vdot(nA,nB))); vaxis_rotate(V,Axis,Angle) #else ((t_parallel(RefA,RefB))*V) #end #end //Obj - base object //S - origin of the fractal, normally you should use <0,0,0> //Dir - local "up" vector, tilting it makes the fractal curl in the opposite direction //LenExp - the amount by which the size of each consecutive instance decreases; // 0.5 - decrease 50% //PA - array of points to which the object is recursively appended //DA - array of directions at those points // (you can usually use the same array as in PA) //N - number of points in those arrays //L - recursion level #macro Recurse(Obj,S,Dir,LenExp,PA,DA,N,L) #ifndef(Li) #local Li=L; #local DirI=Dir; #local PAi=PA #local DAi=DA #local LenExpI=LenExp; #local Len=1; #else #local Len=LenExp; #end #local PAn=array[N] #local DAn=array[N] #local C=0; #while(C #if((t_parallel(DirI,Dir))=0) Reorient(DirI,Dir) #else scale t_parallel(DirI,Dir) #end translate S } #if(L>1) #local C=0; #while(C