[global] procedure rot_i_j(var A,B: matrix; k: integer; theta: real);
var i,j,n: integer;
    s,c: real;
{rotates unitary matrix theta degrees about coorinate k}
begin
   s:=sin(theta);
   c:=cos(theta);
   i:=(k+1) mod 3;
   j:=(k-1) mod 3;
   B:=A;
   for n:=0 to 2 do
      begin
         B[n,i]:=c*A[n,i] - s*A[n,j];
         B[n,j]:=s*A[n,i] + c*A[n,j];
      end;
end;
      

procedure euler_prime(var R:matrix; phi, theta, psi: real);
var A,B,C,D: matrix;
{calculates matrix R which corresponds to euler rotation 
phi,theta,psi}
begin
   A:=unit_matrix(3);
   rot_i_j(A,B,2,phi/deg);
   rot_i_j(B,C,0,theta/deg);
   rot_i_j(C,D,2,psi/deg);
   R:=D;
end;

procedure euler(var A:matrix; var phi,theta,psi: real);
var d,x,y,z,xprime_x,xprime_y,s: real;
{calculates the Euler angles corresponding to rotated coordinates A}
begin
   x:=A[0,2];
   y:=A[1,2];
   z:=A[2,2];
   s:=x/abs(x);
   d:=sqrt(x*x + y*y);
   if z<>0 
      then theta:=s*arctan(d/z)
      else theta:=s*90/deg;
   if y<>0
      then phi:=arctan(-x/y)
      else phi:=90/deg;
   xprime_x:=cos(phi);
   xprime_y:=sin(phi);
   x:=A[0,0];
   y:=A[1,0];
   z:=A[2,0];
   d:=sqrt(x*x + y*y + z*z);
   psi:=deg*arccos((x*xprime_x+y*xprime_y)/d);
   phi:=deg*phi;
   theta:=deg*theta;  
end;

