// draw coordinates and frames
// axis1 is defined by z axis of TBase
// axis2 is defined by z axis of TEnd
void DrawFrame(transform3 TBase, transform3 TEnd, string s)
{
triple p1,v1,p2,v2;
p1=TBase*O;
v1=TBase*Z-p1;
p2=TEnd*O;
v2=TEnd*Z-p2;
triple n=cross(v1,v2);
// draw the coordinates frame
triple dx,dy,dz,org;
real length=0.8;
org=foot1;
dx =length*unit(foot2-foot1); // define the x axis of the frame on "a"
dz =length*unit(v1); // define the z axis which is along axis1
dy =length*unit(cross(dz,dx));
void DrawLink(transform3 TBase, transform3 TEnd, pen objStyle,string s)
{
real h=1;
real r=0.5;
path3 generator=(0.5*r,0,h)--(r,0,h)--(r,0,0)--(0.5*r,0,0);
revolution vase=revolution(O,generator,0,360);
surface objSurface=surface(vase);
render render=render(merge=true);
// draw two cylinders
draw(TBase*objSurface,objStyle,render);
draw(TEnd*shift((0,0,-h+1e-5))*objSurface,objStyle,render);
// draw the link between two cylinders
triple pStart=TBase*(0.5*h*Z);
triple pEnd =TEnd*(-0.5*h*Z);
triple pControl1=0.25*(pEnd-pStart)+TBase*(0,0,h);
triple pControl2=-0.25*(pEnd-pStart)+TEnd*(0,0,-h);
path3 p=pStart..controls pControl1 and pControl2..pEnd;
draw(tube(p,scale(0.2)*unitsquare),objStyle,render);
}
// t1 and t2 define the starting frame and ending frame of the first link(i-1)
transform3 t1=shift((0,0,1));
transform3 t2=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,2));
// as, the two links were connected, so t2 is also the starting frame of link(i)
// t3 defines the ending frame of link(i)
transform3 t3=t2*rotate(40,Z)*shift((0,3,1.5))*rotate(-15,Y)*shift(-1.5*Z);
// draw angle alpha, which is the angle between axis(i-1) and axis(i)
triple p0=(0,0,-1);
triple p1=(0,0,2.3);
triple p2=shift((0,0,-1))*rotate(-20,Y)*(0,0,4);
draw(p0--p2,cyan);
draw("$\alpha_{i-1}$",arc(p0,p1,p2,Y,CW),ArcArrow3(3));
// draw angle theta, which is the angle between a_i and a_{i-1}
transform3 tx=shift((0,0,-1))*rotate(-20,Y)*shift((0,3,0));
p0=tx*O;
p1=tx*(0,3,0);
p2=tx*rotate(40,Z)*(0,3,0);
draw(p0--p1,cyan);
draw(p0--p2,cyan);