home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
COMMON
/
XF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
5KB
|
257 lines
/* Copyright (c) 1991 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)xf.c 2.3 12/24/91 LBL";
#endif
/*
* xf.c - routines to convert transform arguments into 4X4 matrix.
*
* 1/28/86
*/
#include "standard.h"
#define d2r(a) ((PI/180.)*(a))
#define checkarg(a,l) if (av[i][a] || badarg(ac-i-1,av+i+1,l)) goto done
int
xf(ret, ac, av) /* get transform specification */
register XF *ret;
int ac;
char *av[];
{
MAT4 xfmat, m4;
double xfsca, dtmp;
int i, icnt;
setident4(ret->xfm);
ret->sca = 1.0;
icnt = 1;
setident4(xfmat);
xfsca = 1.0;
for (i = 0; i < ac && av[i][0] == '-'; i++) {
setident4(m4);
switch (av[i][1]) {
case 't': /* translate */
checkarg(2,"fff");
m4[3][0] = atof(av[++i]);
m4[3][1] = atof(av[++i]);
m4[3][2] = atof(av[++i]);
break;
case 'r': /* rotate */
switch (av[i][2]) {
case 'x':
checkarg(3,"f");
dtmp = d2r(atof(av[++i]));
m4[1][1] = m4[2][2] = cos(dtmp);
m4[2][1] = -(m4[1][2] = sin(dtmp));
break;
case 'y':
checkarg(3,"f");
dtmp = d2r(atof(av[++i]));
m4[0][0] = m4[2][2] = cos(dtmp);
m4[0][2] = -(m4[2][0] = sin(dtmp));
break;
case 'z':
checkarg(3,"f");
dtmp = d2r(atof(av[++i]));
m4[0][0] = m4[1][1] = cos(dtmp);
m4[1][0] = -(m4[0][1] = sin(dtmp));
break;
default:
goto done;
}
break;
case 's': /* scale */
checkarg(2,"f");
dtmp = atof(av[i+1]);
if (dtmp == 0.0) goto done;
i++;
xfsca *=
m4[0][0] =
m4[1][1] =
m4[2][2] = dtmp;
break;
case 'm': /* mirror */
switch (av[i][2]) {
case 'x':
checkarg(3,"");
xfsca *=
m4[0][0] = -1.0;
break;
case 'y':
checkarg(3,"");
xfsca *=
m4[1][1] = -1.0;
break;
case 'z':
checkarg(3,"");
xfsca *=
m4[2][2] = -1.0;
break;
default:
goto done;
}
break;
case 'i': /* iterate */
checkarg(2,"i");
while (icnt-- > 0) {
multmat4(ret->xfm, ret->xfm, xfmat);
ret->sca *= xfsca;
}
icnt = atoi(av[++i]);
setident4(xfmat);
xfsca = 1.0;
continue;
default:
goto done;
}
multmat4(xfmat, xfmat, m4);
}
done:
while (icnt-- > 0) {
multmat4(ret->xfm, ret->xfm, xfmat);
ret->sca *= xfsca;
}
return(i);
}
int
invxf(ret, ac, av) /* invert transform specification */
register XF *ret;
int ac;
char *av[];
{
MAT4 xfmat, m4;
double xfsca, dtmp;
int i, icnt;
setident4(ret->xfm);
ret->sca = 1.0;
icnt = 1;
setident4(xfmat);
xfsca = 1.0;
for (i = 0; i < ac && av[i][0] == '-'; i++) {
setident4(m4);
switch (av[i][1]) {
case 't': /* translate */
checkarg(2,"fff");
m4[3][0] = -atof(av[++i]);
m4[3][1] = -atof(av[++i]);
m4[3][2] = -atof(av[++i]);
break;
case 'r': /* rotate */
switch (av[i][2]) {
case 'x':
checkarg(3,"f");
dtmp = -d2r(atof(av[++i]));
m4[1][1] = m4[2][2] = cos(dtmp);
m4[2][1] = -(m4[1][2] = sin(dtmp));
break;
case 'y':
checkarg(3,"f");
dtmp = -d2r(atof(av[++i]));
m4[0][0] = m4[2][2] = cos(dtmp);
m4[0][2] = -(m4[2][0] = sin(dtmp));
break;
case 'z':
checkarg(3,"f");
dtmp = -d2r(atof(av[++i]));
m4[0][0] = m4[1][1] = cos(dtmp);
m4[1][0] = -(m4[0][1] = sin(dtmp));
break;
default:
goto done;
}
break;
case 's': /* scale */
checkarg(2,"f");
dtmp = atof(av[i+1]);
if (dtmp == 0.0) goto done;
i++;
xfsca *=
m4[0][0] =
m4[1][1] =
m4[2][2] = 1.0 / dtmp;
break;
case 'm': /* mirror */
switch (av[i][2]) {
case 'x':
checkarg(3,"");
xfsca *=
m4[0][0] = -1.0;
break;
case 'y':
checkarg(3,"");
xfsca *=
m4[1][1] = -1.0;
break;
case 'z':
checkarg(3,"");
xfsca *=
m4[2][2] = -1.0;
break;
default:
goto done;
}
break;
case 'i': /* iterate */
checkarg(2,"i");
while (icnt-- > 0) {
multmat4(ret->xfm, xfmat, ret->xfm);
ret->sca *= xfsca;
}
icnt = atoi(av[++i]);
setident4(xfmat);
xfsca = 1.0;
break;
default:
goto done;
}
multmat4(xfmat, m4, xfmat); /* left multiply */
}
done:
while (icnt-- > 0) {
multmat4(ret->xfm, xfmat, ret->xfm);
ret->sca *= xfsca;
}
return(i);
}
int
fullxf(fx, ac, av) /* compute both forward and inverse */
FULLXF *fx;
int ac;
char *av[];
{
xf(&fx->f, ac, av);
return(invxf(&fx->b, ac, av));
}