/* RCRCR  program used in paper
   "Computer-Aided Displacement Analysis of Spatial Mechanisms
   Using the CH Programming Language",
   Advances in Engineering Software
   by  Cheng, H. H., and Thompson, S.
*/
#include <linkage.h>
main()
{
  dual   alpha1,alpha2,alpha3,alpha4,alpha5,theta1,theta2,theta3,theta4,theta5;
  dual   A,B,C,D,E,F,G,A1,B1,C1,D1,A2,B2,C2,D2;
  float  theta1_i,d1,d2,d3,d4,d5,x,p[5],roots[4],tolerance = 0.001;
  int    i;                          /* branch number */
  FILE   *stream;
  local void plotRCRCR(char *filename);

  stream = fopen("RCRCR.out","w");   /* open file RCRCR.out */
  fprintf(stream, "%%  theta 1  theta 2  d2(cm)   theta 3  theta 4  d4(cm)   theta 5 \n");
  /*******************   INITIALIZE VARIABLES   ******************************/
  d1=0.0; d3=2.50; d5=3.00;          /* fixed displacements of the RCRCR mechanism */
  alpha1=dual(30*PI/180,1);          /* fixed dual angles of the RCRCR mechanism */
  alpha2=dual(35*PI/180,4.0); alpha3=dual(45*PI/180,3.0);
  alpha4=dual(60*PI/180,2.5); alpha5=dual(10*PI/180,3.2);
  for (theta1_i=60; theta1_i <=420; theta1_i++) /* 60 <= theta1 <=420 */
  {
    fprintf(stream,"%% \n");         /* add space between sets of data */
    theta1=dual(theta1_i*PI/180,d1);
    A=cos(alpha2)*cos(alpha3)-(cos(alpha4)*(cos(alpha5)*cos(alpha1)-
      sin(alpha5)*sin(alpha1)*cos(theta1)));                               /* (24) */
    B=sin(alpha2)*sin(alpha3);                                             /* (25) */
    C=sin(alpha1)*sin(alpha4)*sin(theta1);                                 /* (26) */
    D=sin(alpha4)*(sin(alpha5)*cos(alpha1)+
      cos(alpha5)*sin(alpha1)*cos(theta1));                                /* (27) */
    E=(A+C*dual(0,d5)-D)/B;                                                /* (33) */
    F=(C+dual(0,d5)*D)/B;                                                  /* (34) */
    G=(A-dual(0,d5)*C+D)/B;                                                /* (35) */
    p[4]=pow(real(E),2)+pow(dual(E),2)/(d3*d3)-1;                          /* (40) */
    p[3]=-4*(real(E)*real(F)+dual(E)*dual(F)/(d3*d3));                     /* (41) */
    p[2]=2*real(E)*real(G)+4*pow(real(F),2)+(2*dual(E)*dual(G)+        
         4*pow(dual(F),2))/(d3*d3)-2;                                      /* (42) */ 
    p[1]=-4*(real(F)*real(G)+dual(F)*dual(G)/(d3*d3));                     /* (43) */
    p[0]=pow(real(G),2)+pow(dual(G),2)/(d3*d3)-1;                          /* (44) */
    roots[0] = 0; roots[1] = 0; roots[2] =0; roots[3] =0;
    zroots(p,4,roots,1);             /* Solve polynomial equation             (39) */
    for(i=0; i<=3; i++)              /* 4 branches of the RCRCR mechanism */
    {
      x = roots[i];
      theta3=dual(2*atan(dual(E*x*x-2*F*x+G)/
                 (-d3*real((E+1)*x*x-2*F*x+G+1))),d3);                     /* (46) */
      theta5=dual((2*atan(x)),d5);
      A1=(cos(alpha4)*sin(alpha5)+sin(alpha4)*cos(alpha5)*cos(theta5))*
         sin(theta1)+sin(alpha4)*cos(theta1)*sin(theta5);                  /* (49) */
      B1=(cos(alpha5)*sin(alpha1)+sin(alpha5)*cos(alpha1)*cos(theta1))*
         cos(alpha4)-((sin(alpha5)*sin(alpha1)-cos(alpha5)*cos(alpha1)*
         cos(theta1))*cos(theta5)+cos(alpha1)*sin(theta1)
         *sin(theta5))*sin(alpha4);                                        /* (50) */
      C1=sin(alpha3)*sin(theta3);                                          /* (51) */
      D1=sin(alpha2)*cos(alpha3)+cos(alpha2)*sin(alpha3)*cos(theta3);      /* (52) */
      theta2=2*atan((A1*D1+B1*C1)/(C1*C1+D1*D1+A1*C1-B1*D1));              /* (53) */
      A2=(sin(alpha5)*cos(alpha1)+cos(alpha5)*sin(alpha1)*cos(theta1))*
         sin(theta5)+sin(alpha1)*sin(theta1)*cos(theta5);                  /* (56) */
      B2=(cos(alpha5)*cos(alpha1)-sin(alpha5)*sin(alpha1)*cos(theta1))*
         sin(alpha4)+((sin(alpha5)*cos(alpha1)+cos(alpha5)*sin(alpha1)*
         cos(theta1))*cos(theta5)-sin(alpha1)*sin(theta1)* 
         sin(theta5))*cos(alpha4);                                         /* (57) */
      C2=sin(alpha2)*sin(theta3);                                          /* (58) */
      D2=cos(alpha2)*sin(alpha3)+sin(alpha2)*cos(alpha3)*cos(theta3);      /* (59) */
      theta4=2*atan((A2*D2+B2*C2)/(C2*C2+D2*D2+A2*C2-B2*D2));              /* (60) */
    /*********************    PRINT RESULTS    ***********************/
      if (real(theta5)*180/PI > 150)      /* adjust for clear plots */
        real(theta5) = real(theta5-2*PI); /* adjust real part of theta5 */
      if (real(theta4)*180/PI < 0) 
        real(theta4) = real(theta4+2*PI); /* adjust real part of theta4 */
      fprintf(stream," %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f \n",
              theta1_i,real(theta2)*180/PI,dual(theta2),real(theta3)*180/PI,
              real(theta4)*180/PI,dual(theta4),real(theta5)*180/PI);
    }
  }
  fclose(stream);                         /* close file RCRCR.out */
  plotRCRCR("RCRCR.out");                 /* make labels and plots 6 graphs */
  remove("RCRCR.out");                    /* remove RCRCR.out file  */
 
  /** local function plotRCRCR() **/
  void plotRCRCR(char *filename)
  {
    char plotnum[64], num[11];
    int n = 6;
    int i;
    char *title[6]  = {" "," "," "," "," "," "}
    char *xlabel[6] = {"Theta 1 (degrees)","Theta 1 (degrees)","Theta 1 (degrees)",
                       "Theta 1 (degrees)","Theta 1 (degrees)","Theta 1 (degrees)"};
    char *ylabel[6] = {"Theta 2 (degrees)","d2 (centimeters)","Theta 3 (degrees)",
                       "Theta 4 (degrees)","d4 (centimeters)","Theta 5 (degrees)"};
    int x1[6] = {60,60,60,60,60,60};         /* low range of x-axis */
    int x2[6] = {420,420,420,420,420,420};   /* high range of  x-axis */
    int y1[6] = {-180,-10,-180,60,-14,-210}; /* low range of plo ts */
    int y2[6] = {180,10,180,420,14,150};     /* high range of plots */
    int xint[6]  = {120,120,120,120,120,120} /* interval of y-axis plot */
    int yint[6]  = {120,4,120,120,4,120};    /* interval of y-axis plot */
    int xtic[6]  = {3,3,3,3,3,3}             /* number of x tics */
    int ytic[6]  = {3,3,3,3,3,3}             /* number of y tics */
    separate(filename,n);                    /* separate RCRCR.out into 6 files */
    for(i=0;i<=n-1;i++)
    {
      sprintf(num,i+1);
      strcpy(plotnum, "plot");
      strcat(plotnum,num);
      strcat(plotnum,".out");
      plotxyrf(plotnum,title[i],xlabel[i],ylabel[i],x1[i],x2[i],
               xint[i],y1[i],y2[i],yint[i]);
      remove(plotnum);                    /* remove plotnum created by separate() */
    }
  }  
}
