Back to index

radiance  4R0+20100331
genworm.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: genworm.c,v 2.8 2004/08/21 11:54:06 greg Exp $";
00003 #endif
00004 /*
00005  *  genworm.c - program to generate worms (strings with varying thickness).
00006  *
00007  *     The program takes as input the functions of t for x, y,
00008  *     z and r (the radius).  Cylinders and cones will be
00009  *     joined by spheres.  Negative radii are forbidden.
00010  *
00011  *     9/24/87
00012  */
00013 
00014 #include  <stdlib.h>
00015 #include  <stdio.h>
00016 #include  <math.h>
00017 #include  <string.h>
00018 
00019 #include  "calcomp.h"
00020 #include  "resolu.h"
00021 #include  "rterror.h"
00022 #include  "fvect.h"
00023 
00024 #define  XNAME              "X`SYS`"             /* x function name */
00025 #define  YNAME              "Y`SYS`"             /* y function name */
00026 #define  ZNAME              "Z`SYS`"             /* z function name */
00027 #define  RNAME              "R`SYS`"             /* r function name */
00028 
00029 #define  PI          3.14159265358979323846
00030 
00031 #define  max(a,b)    ((a) > (b) ? (a) : (b))
00032 
00033 
00034 /* XXX redundant, move to library */
00035 double  l_hermite(char *), l_bezier(char *), l_bspline(char *);
00036 
00037 
00038 int
00039 main(argc, argv)
00040 int  argc;
00041 char  *argv[];
00042 {
00043        char  stmp[256];
00044        double  t, f, lastr = 0, r;
00045        FVECT  lastp, p;
00046        int  i, nseg;
00047 
00048        varset("PI", ':', PI);
00049        funset("hermite", 5, ':', l_hermite);
00050        funset("bezier", 5, ':', l_bezier);
00051        funset("bspline", 5, ':', l_bspline);
00052 
00053        if (argc < 8)
00054               goto userror;
00055 
00056        for (i = 8; i < argc; i++)
00057               if (!strcmp(argv[i], "-e"))
00058                      scompile(argv[++i], NULL, 0);
00059               else if (!strcmp(argv[i], "-f"))
00060                      fcompile(argv[++i]);
00061               else
00062                      goto userror;
00063 
00064        sprintf(stmp, "%s(t)=%s;", XNAME, argv[3]);
00065        scompile(stmp, NULL, 0);
00066        sprintf(stmp, "%s(t)=%s;", YNAME, argv[4]);
00067        scompile(stmp, NULL, 0);
00068        sprintf(stmp, "%s(t)=%s;", ZNAME, argv[5]);
00069        scompile(stmp, NULL, 0);
00070        sprintf(stmp, "%s(t)=%s;", RNAME, argv[6]);
00071        scompile(stmp, NULL, 0);
00072        nseg = atoi(argv[7]);
00073        if (nseg <= 0)
00074               goto userror;
00075 
00076        fputs("# ", stdout);
00077        printargs(argc, argv, stdout);
00078        eclock = 0;
00079 
00080        for (i = 0; i <= nseg; i++) {
00081               t = (double)i/nseg;
00082               p[0] = funvalue(XNAME, 1, &t);
00083               p[1] = funvalue(YNAME, 1, &t);
00084               p[2] = funvalue(ZNAME, 1, &t);
00085               r = funvalue(RNAME, 1, &t);
00086               if (i) {
00087                      if (lastr <= r+FTINY && lastr >= r-FTINY) {
00088                             printf("\n%s cylinder %s.c%d\n",
00089                                           argv[1], argv[2], i);
00090                             printf("0\n0\n7\n");
00091                             printf("%18.12g %18.12g %18.12g\n",
00092                                           lastp[0], lastp[1], lastp[2]);
00093                             printf("%18.12g %18.12g %18.12g\n",
00094                                           p[0], p[1], p[2]);
00095                             printf("%18.12g\n", r);
00096                      } else {
00097                             printf("\n%s cone %s.c%d\n",
00098                                           argv[1], argv[2], i);
00099                             printf("0\n0\n8\n");
00100                             f = (lastr - r)/dist2(lastp,p);
00101                             printf("%18.12g %18.12g %18.12g\n",
00102                                    lastp[0] + f*lastr*(p[0] - lastp[0]),
00103                                    lastp[1] + f*lastr*(p[1] - lastp[1]),
00104                                    lastp[2] + f*lastr*(p[2] - lastp[2]));
00105                             printf("%18.12g %18.12g %18.12g\n",
00106                                    p[0] + f*r*(p[0] - lastp[0]),
00107                                    p[1] + f*r*(p[1] - lastp[1]),
00108                                    p[2] + f*r*(p[2] - lastp[2]));
00109                             f = 1.0 - (lastr-r)*f;
00110                             f = f <= 0.0 ? 0.0 : sqrt(f);
00111                             printf("%18.12g %18.12g\n", f*lastr, f*r);
00112                      }
00113               }
00114               printf("\n%s sphere %s.s%d\n", argv[1], argv[2], i);
00115               printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
00116                             p[0], p[1], p[2], r);
00117               VCOPY(lastp, p);
00118               lastr = r;
00119        }
00120        return 0;
00121 
00122 userror:
00123        fprintf(stderr,
00124 "Usage: %s material name x(t) y(t) z(t) r(t) nseg [-e expr] [-f file]\n",
00125                      argv[0]);
00126        return 1;
00127 }
00128 
00129 
00130 double
00131 l_hermite(char *nm)
00132 {
00133        double  t;
00134        
00135        t = argument(5);
00136        return(       argument(1)*((2.0*t-3.0)*t*t+1.0) +
00137               argument(2)*(-2.0*t+3.0)*t*t +
00138               argument(3)*((t-2.0)*t+1.0)*t +
00139               argument(4)*(t-1.0)*t*t );
00140 }
00141 
00142 
00143 double
00144 l_bezier(char *nm)
00145 {
00146        double  t;
00147 
00148        t = argument(5);
00149        return(       argument(1) * (1.+t*(-3.+t*(3.-t))) +
00150               argument(2) * 3.*t*(1.+t*(-2.+t)) +
00151               argument(3) * 3.*t*t*(1.-t) +
00152               argument(4) * t*t*t );
00153 }
00154 
00155 
00156 double
00157 l_bspline(char *nm)
00158 {
00159        double  t;
00160 
00161        t = argument(5);
00162        return(       argument(1) * (1./6.+t*(-1./2.+t*(1./2.-1./6.*t))) +
00163               argument(2) * (2./3.+t*t*(-1.+1./2.*t)) +
00164               argument(3) * (1./6.+t*(1./2.+t*(1./2.-1./2.*t))) +
00165               argument(4) * (1./6.*t*t*t) );
00166 }