Back to index

radiance  4R0+20100331
xf.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: xf.c,v 2.7 2003/06/27 22:27:45 greg Exp $";
00003 #endif
00004 /*
00005  *  xf.c - routines to convert transform arguments into 4X4 matrix.
00006  *
00007  *  External symbols declared in rtmath.h
00008  */
00009 
00010 #include  <stdlib.h>
00011 #include  "rtmath.h"
00012 #include  "rtio.h"
00013 
00014 #define  d2r(a)             ((PI/180.)*(a))
00015 
00016 #define  checkarg(a,l)      if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
00017 
00018 
00019 int
00020 xf(ret, ac, av)                    /* get transform specification */
00021 register XF  *ret;
00022 int  ac;
00023 char  *av[];
00024 {
00025        MAT4  xfmat, m4;
00026        double  xfsca, dtmp;
00027        int  i, icnt;
00028 
00029        setident4(ret->xfm);
00030        ret->sca = 1.0;
00031 
00032        icnt = 1;
00033        setident4(xfmat);
00034        xfsca = 1.0;
00035 
00036        for (i = 0; i < ac && av[i][0] == '-'; i++) {
00037        
00038               setident4(m4);
00039               
00040               switch (av[i][1]) {
00041        
00042               case 't':                   /* translate */
00043                      checkarg(2,"fff");
00044                      m4[3][0] = atof(av[++i]);
00045                      m4[3][1] = atof(av[++i]);
00046                      m4[3][2] = atof(av[++i]);
00047                      break;
00048 
00049               case 'r':                   /* rotate */
00050                      switch (av[i][2]) {
00051                      case 'x':
00052                             checkarg(3,"f");
00053                             dtmp = d2r(atof(av[++i]));
00054                             m4[1][1] = m4[2][2] = cos(dtmp);
00055                             m4[2][1] = -(m4[1][2] = sin(dtmp));
00056                             break;
00057                      case 'y':
00058                             checkarg(3,"f");
00059                             dtmp = d2r(atof(av[++i]));
00060                             m4[0][0] = m4[2][2] = cos(dtmp);
00061                             m4[0][2] = -(m4[2][0] = sin(dtmp));
00062                             break;
00063                      case 'z':
00064                             checkarg(3,"f");
00065                             dtmp = d2r(atof(av[++i]));
00066                             m4[0][0] = m4[1][1] = cos(dtmp);
00067                             m4[1][0] = -(m4[0][1] = sin(dtmp));
00068                             break;
00069                      default:
00070                             goto done;
00071                      }
00072                      break;
00073 
00074               case 's':                   /* scale */
00075                      checkarg(2,"f");
00076                      dtmp = atof(av[i+1]);
00077                      if (dtmp == 0.0) goto done;
00078                      i++;
00079                      xfsca *=
00080                      m4[0][0] = 
00081                      m4[1][1] = 
00082                      m4[2][2] = dtmp;
00083                      break;
00084 
00085               case 'm':                   /* mirror */
00086                      switch (av[i][2]) {
00087                      case 'x':
00088                             checkarg(3,"");
00089                             xfsca *=
00090                             m4[0][0] = -1.0;
00091                             break;
00092                      case 'y':
00093                             checkarg(3,"");
00094                             xfsca *=
00095                             m4[1][1] = -1.0;
00096                             break;
00097                      case 'z':
00098                             checkarg(3,"");
00099                             xfsca *=
00100                             m4[2][2] = -1.0;
00101                             break;
00102                      default:
00103                             goto done;
00104                      }
00105                      break;
00106 
00107               case 'i':                   /* iterate */
00108                      checkarg(2,"i");
00109                      while (icnt-- > 0) {
00110                             multmat4(ret->xfm, ret->xfm, xfmat);
00111                             ret->sca *= xfsca;
00112                      }
00113                      icnt = atoi(av[++i]);
00114                      setident4(xfmat);
00115                      xfsca = 1.0;
00116                      continue;
00117 
00118               default:
00119                      goto done;
00120 
00121               }
00122               multmat4(xfmat, xfmat, m4);
00123        }
00124 done:
00125        while (icnt-- > 0) {
00126               multmat4(ret->xfm, ret->xfm, xfmat);
00127               ret->sca *= xfsca;
00128        }
00129        return(i);
00130 }
00131 
00132 
00133 int
00134 invxf(ret, ac, av)          /* invert transform specification */
00135 register XF  *ret;
00136 int  ac;
00137 char  *av[];
00138 {
00139        MAT4  xfmat, m4;
00140        double  xfsca, dtmp;
00141        int  i, icnt;
00142 
00143        setident4(ret->xfm);
00144        ret->sca = 1.0;
00145 
00146        icnt = 1;
00147        setident4(xfmat);
00148        xfsca = 1.0;
00149 
00150        for (i = 0; i < ac && av[i][0] == '-'; i++) {
00151        
00152               setident4(m4);
00153               
00154               switch (av[i][1]) {
00155        
00156               case 't':                   /* translate */
00157                      checkarg(2,"fff");
00158                      m4[3][0] = -atof(av[++i]);
00159                      m4[3][1] = -atof(av[++i]);
00160                      m4[3][2] = -atof(av[++i]);
00161                      break;
00162 
00163               case 'r':                   /* rotate */
00164                      switch (av[i][2]) {
00165                      case 'x':
00166                             checkarg(3,"f");
00167                             dtmp = -d2r(atof(av[++i]));
00168                             m4[1][1] = m4[2][2] = cos(dtmp);
00169                             m4[2][1] = -(m4[1][2] = sin(dtmp));
00170                             break;
00171                      case 'y':
00172                             checkarg(3,"f");
00173                             dtmp = -d2r(atof(av[++i]));
00174                             m4[0][0] = m4[2][2] = cos(dtmp);
00175                             m4[0][2] = -(m4[2][0] = sin(dtmp));
00176                             break;
00177                      case 'z':
00178                             checkarg(3,"f");
00179                             dtmp = -d2r(atof(av[++i]));
00180                             m4[0][0] = m4[1][1] = cos(dtmp);
00181                             m4[1][0] = -(m4[0][1] = sin(dtmp));
00182                             break;
00183                      default:
00184                             goto done;
00185                      }
00186                      break;
00187 
00188               case 's':                   /* scale */
00189                      checkarg(2,"f");
00190                      dtmp = atof(av[i+1]);
00191                      if (dtmp == 0.0) goto done;
00192                      i++;
00193                      xfsca *=
00194                      m4[0][0] = 
00195                      m4[1][1] = 
00196                      m4[2][2] = 1.0 / dtmp;
00197                      break;
00198 
00199               case 'm':                   /* mirror */
00200                      switch (av[i][2]) {
00201                      case 'x':
00202                             checkarg(3,"");
00203                             xfsca *=
00204                             m4[0][0] = -1.0;
00205                             break;
00206                      case 'y':
00207                             checkarg(3,"");
00208                             xfsca *=
00209                             m4[1][1] = -1.0;
00210                             break;
00211                      case 'z':
00212                             checkarg(3,"");
00213                             xfsca *=
00214                             m4[2][2] = -1.0;
00215                             break;
00216                      default:
00217                             goto done;
00218                      }
00219                      break;
00220 
00221               case 'i':                   /* iterate */
00222                      checkarg(2,"i");
00223                      while (icnt-- > 0) {
00224                             multmat4(ret->xfm, xfmat, ret->xfm);
00225                             ret->sca *= xfsca;
00226                      }
00227                      icnt = atoi(av[++i]);
00228                      setident4(xfmat);
00229                      xfsca = 1.0;
00230                      break;
00231 
00232               default:
00233                      goto done;
00234 
00235               }
00236               multmat4(xfmat, m4, xfmat); /* left multiply */
00237        }
00238 done:
00239        while (icnt-- > 0) {
00240               multmat4(ret->xfm, xfmat, ret->xfm);
00241               ret->sca *= xfsca;
00242        }
00243        return(i);
00244 }
00245 
00246 
00247 int
00248 fullxf(fx, ac, av)                 /* compute both forward and inverse */
00249 FULLXF  *fx;
00250 int  ac;
00251 char  *av[];
00252 {
00253        xf(&fx->f, ac, av);
00254        return(invxf(&fx->b, ac, av));
00255 }