/* How to make an IK leg - by Rune S. Johansen This scene can be rendered as a small cyclic animation with the clock going from 0 to 1. */ #default {pigment {color rgb 1}} light_source {<3,2,1>*1000, color 1} camera {location <3,0.5,0> look_at 0.5*y} /* "H. E. Day" wrote: > I only want to have to move the ankle for the entire > leg to move accordingly. You need to specify 5 things: */ #declare HipPoint = 1.5*y; #declare AnklePoint = 0.1*y + vrotate(0.2*y,360*x*clock); #declare ThighLength = 1; #declare ShinLength = 1; #declare KneeDirection = z; /* > The leg doesn't need to be anything fancy, just 3 > spheres (Hip, Knee, Ankle) and 2 cylinders (Thigh, Shin). Ok, first you need a macro that finds the knee point. Here it is, but unfortunately right now I can't remember who made it. */ #macro Knee(pA,pH,lT,lS,vD) #local lB=vlength(pA-(pH)); #if( (lB>lT+lS) | (lT>lB+lS) | (lS>lT+lB) ) #error "Invalid span lengths.\n" #end #local tS=(lT+lS+lB)/2; #local tA=sqrt(tS*(tS-(lT))*(tS-(lS))*(tS-lB)); #local tH=tA*2/lB; #local vO=vnormalize(pA-(pH)); #local vF=vnormalize(vcross(vD,vO)); #local vU=vnormalize(vcross(vO,vF)); (pH+vO*sqrt((lT)*(lT)-tH*tH)+vU*tH) #end // Now calculate the knee point. #declare KneePoint = Knee(HipPoint,AnklePoint,ShinLength,ThighLength,KneeDirection); /* Now have enough data to make a spheres + cylinders leg... > I'll replace the objects with the stuff I've already > have built. ...but that makes it slightly more complicated. I'll presume that your thigh object is centered around the hip and extents down the -y axis, and that your shin object is centered around the knee and extents down the -y axis. */ #declare ThighObject = union { sphere {0*y, 0.2} box {<-0.1,-1,-0.1>, <0.1,0,0.1> rotate 45*y} sphere {-1*y, 0.2} } #declare ShinObject = union { box {<-0.1,-1,-0.1>, <0.1,0,0.1> rotate 45*y} sphere {-1*y, 0.2} } /* Now you need matrixes that transforms them into the right positions. A simple macro can convert 4 vectors into a matrix. */ #macro Vectors2Matrix (vA,vB,vC,vD) matrix #end // This macro also comes in handy: #macro Perpendiculize (V1,V2) vnormalize(vcross(vcross(V2,V1),V2)) #end // Anyway, you need these 4 vectors: #declare ThighY = vnormalize(HipPoint-KneePoint); #declare ThighZ = Perpendiculize(KneeDirection,ThighY); #declare ThighX = vcross(ThighY,ThighZ); #declare ThighP = HipPoint; // Now convert them into a matrix: #declare ThighTransform = transform{Vectors2Matrix(ThighX,ThighY,ThighZ,ThighP)} // You also need to do similar calculations for the Shin: #declare ShinY = vnormalize(KneePoint-AnklePoint); #declare ShinZ = Perpendiculize(KneeDirection,ShinY); #declare ShinX = vcross(ShinY,ShinZ); #declare ShinP = KneePoint; #declare ShinTransform = transform{Vectors2Matrix(ShinX,ShinY,ShinZ,ShinP)} // Now create the leg object {ThighObject transform ThighTransform} object {ShinObject transform ShinTransform} // Hope this help!