home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / COMMON / XF.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  5KB  |  257 lines

  1. /* Copyright (c) 1991 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)xf.c 2.3 12/24/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  xf.c - routines to convert transform arguments into 4X4 matrix.
  9.  *
  10.  *     1/28/86
  11.  */
  12.  
  13. #include  "standard.h"
  14.  
  15. #define  d2r(a)        ((PI/180.)*(a))
  16.  
  17. #define  checkarg(a,l)    if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
  18.  
  19.  
  20. int
  21. xf(ret, ac, av)            /* get transform specification */
  22. register XF  *ret;
  23. int  ac;
  24. char  *av[];
  25. {
  26.     MAT4  xfmat, m4;
  27.     double  xfsca, dtmp;
  28.     int  i, icnt;
  29.  
  30.     setident4(ret->xfm);
  31.     ret->sca = 1.0;
  32.  
  33.     icnt = 1;
  34.     setident4(xfmat);
  35.     xfsca = 1.0;
  36.  
  37.     for (i = 0; i < ac && av[i][0] == '-'; i++) {
  38.     
  39.         setident4(m4);
  40.         
  41.         switch (av[i][1]) {
  42.     
  43.         case 't':            /* translate */
  44.             checkarg(2,"fff");
  45.             m4[3][0] = atof(av[++i]);
  46.             m4[3][1] = atof(av[++i]);
  47.             m4[3][2] = atof(av[++i]);
  48.             break;
  49.  
  50.         case 'r':            /* rotate */
  51.             switch (av[i][2]) {
  52.             case 'x':
  53.                 checkarg(3,"f");
  54.                 dtmp = d2r(atof(av[++i]));
  55.                 m4[1][1] = m4[2][2] = cos(dtmp);
  56.                 m4[2][1] = -(m4[1][2] = sin(dtmp));
  57.                 break;
  58.             case 'y':
  59.                 checkarg(3,"f");
  60.                 dtmp = d2r(atof(av[++i]));
  61.                 m4[0][0] = m4[2][2] = cos(dtmp);
  62.                 m4[0][2] = -(m4[2][0] = sin(dtmp));
  63.                 break;
  64.             case 'z':
  65.                 checkarg(3,"f");
  66.                 dtmp = d2r(atof(av[++i]));
  67.                 m4[0][0] = m4[1][1] = cos(dtmp);
  68.                 m4[1][0] = -(m4[0][1] = sin(dtmp));
  69.                 break;
  70.             default:
  71.                 goto done;
  72.             }
  73.             break;
  74.  
  75.         case 's':            /* scale */
  76.             checkarg(2,"f");
  77.             dtmp = atof(av[i+1]);
  78.             if (dtmp == 0.0) goto done;
  79.             i++;
  80.             xfsca *=
  81.             m4[0][0] = 
  82.             m4[1][1] = 
  83.             m4[2][2] = dtmp;
  84.             break;
  85.  
  86.         case 'm':            /* mirror */
  87.             switch (av[i][2]) {
  88.             case 'x':
  89.                 checkarg(3,"");
  90.                 xfsca *=
  91.                 m4[0][0] = -1.0;
  92.                 break;
  93.             case 'y':
  94.                 checkarg(3,"");
  95.                 xfsca *=
  96.                 m4[1][1] = -1.0;
  97.                 break;
  98.             case 'z':
  99.                 checkarg(3,"");
  100.                 xfsca *=
  101.                 m4[2][2] = -1.0;
  102.                 break;
  103.             default:
  104.                 goto done;
  105.             }
  106.             break;
  107.  
  108.         case 'i':            /* iterate */
  109.             checkarg(2,"i");
  110.             while (icnt-- > 0) {
  111.                 multmat4(ret->xfm, ret->xfm, xfmat);
  112.                 ret->sca *= xfsca;
  113.             }
  114.             icnt = atoi(av[++i]);
  115.             setident4(xfmat);
  116.             xfsca = 1.0;
  117.             continue;
  118.  
  119.         default:
  120.             goto done;
  121.  
  122.         }
  123.         multmat4(xfmat, xfmat, m4);
  124.     }
  125. done:
  126.     while (icnt-- > 0) {
  127.         multmat4(ret->xfm, ret->xfm, xfmat);
  128.         ret->sca *= xfsca;
  129.     }
  130.     return(i);
  131. }
  132.  
  133.  
  134. int
  135. invxf(ret, ac, av)        /* invert transform specification */
  136. register XF  *ret;
  137. int  ac;
  138. char  *av[];
  139. {
  140.     MAT4  xfmat, m4;
  141.     double  xfsca, dtmp;
  142.     int  i, icnt;
  143.  
  144.     setident4(ret->xfm);
  145.     ret->sca = 1.0;
  146.  
  147.     icnt = 1;
  148.     setident4(xfmat);
  149.     xfsca = 1.0;
  150.  
  151.     for (i = 0; i < ac && av[i][0] == '-'; i++) {
  152.     
  153.         setident4(m4);
  154.         
  155.         switch (av[i][1]) {
  156.     
  157.         case 't':            /* translate */
  158.             checkarg(2,"fff");
  159.             m4[3][0] = -atof(av[++i]);
  160.             m4[3][1] = -atof(av[++i]);
  161.             m4[3][2] = -atof(av[++i]);
  162.             break;
  163.  
  164.         case 'r':            /* rotate */
  165.             switch (av[i][2]) {
  166.             case 'x':
  167.                 checkarg(3,"f");
  168.                 dtmp = -d2r(atof(av[++i]));
  169.                 m4[1][1] = m4[2][2] = cos(dtmp);
  170.                 m4[2][1] = -(m4[1][2] = sin(dtmp));
  171.                 break;
  172.             case 'y':
  173.                 checkarg(3,"f");
  174.                 dtmp = -d2r(atof(av[++i]));
  175.                 m4[0][0] = m4[2][2] = cos(dtmp);
  176.                 m4[0][2] = -(m4[2][0] = sin(dtmp));
  177.                 break;
  178.             case 'z':
  179.                 checkarg(3,"f");
  180.                 dtmp = -d2r(atof(av[++i]));
  181.                 m4[0][0] = m4[1][1] = cos(dtmp);
  182.                 m4[1][0] = -(m4[0][1] = sin(dtmp));
  183.                 break;
  184.             default:
  185.                 goto done;
  186.             }
  187.             break;
  188.  
  189.         case 's':            /* scale */
  190.             checkarg(2,"f");
  191.             dtmp = atof(av[i+1]);
  192.             if (dtmp == 0.0) goto done;
  193.             i++;
  194.             xfsca *=
  195.             m4[0][0] = 
  196.             m4[1][1] = 
  197.             m4[2][2] = 1.0 / dtmp;
  198.             break;
  199.  
  200.         case 'm':            /* mirror */
  201.             switch (av[i][2]) {
  202.             case 'x':
  203.                 checkarg(3,"");
  204.                 xfsca *=
  205.                 m4[0][0] = -1.0;
  206.                 break;
  207.             case 'y':
  208.                 checkarg(3,"");
  209.                 xfsca *=
  210.                 m4[1][1] = -1.0;
  211.                 break;
  212.             case 'z':
  213.                 checkarg(3,"");
  214.                 xfsca *=
  215.                 m4[2][2] = -1.0;
  216.                 break;
  217.             default:
  218.                 goto done;
  219.             }
  220.             break;
  221.  
  222.         case 'i':            /* iterate */
  223.             checkarg(2,"i");
  224.             while (icnt-- > 0) {
  225.                 multmat4(ret->xfm, xfmat, ret->xfm);
  226.                 ret->sca *= xfsca;
  227.             }
  228.             icnt = atoi(av[++i]);
  229.             setident4(xfmat);
  230.             xfsca = 1.0;
  231.             break;
  232.  
  233.         default:
  234.             goto done;
  235.  
  236.         }
  237.         multmat4(xfmat, m4, xfmat);    /* left multiply */
  238.     }
  239. done:
  240.     while (icnt-- > 0) {
  241.         multmat4(ret->xfm, xfmat, ret->xfm);
  242.         ret->sca *= xfsca;
  243.     }
  244.     return(i);
  245. }
  246.  
  247.  
  248. int
  249. fullxf(fx, ac, av)            /* compute both forward and inverse */
  250. FULLXF  *fx;
  251. int  ac;
  252. char  *av[];
  253. {
  254.     xf(&fx->f, ac, av);
  255.     return(invxf(&fx->b, ac, av));
  256. }
  257.