Back to index

radiance  4R0+20100331
genbranch.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: genbranch.c,v 2.7 2003/11/16 10:29:38 schorsch Exp $";
00003 #endif
00004 /*
00005  *  genbranch.c - program to generate 3D Christmas tree branches.
00006  *
00007  *     8/23/86
00008  */
00009 
00010 #include  <stdio.h>
00011 
00012 #include <stdlib.h>
00013 
00014 #include  <math.h>
00015 
00016 #include  "random.h"
00017 
00018 #define  errf()             (var*(0.5-frandom()))
00019 
00020 double  bstart[3] = {0.0, 0.0, 0.0};      /* start of branch */
00021 double  bend[3] = {28.0, 8.0, 0.0};       /* end of branch */
00022 double  bthick = .6;               /* branch radius at base */
00023 double  bnarrow = .4;                     /* ratio of tip radius to base */
00024 double  bratio = .4;               /* ratio of limb to branch */
00025 char  *branchmat = "m_bark";              /* bark material */
00026 
00027 char  *leafmat = "m_leaf";         /* leaf material */
00028 
00029 int  nshoots = 7;                  /* number of offshoots */
00030 int  rdepth = 3;                   /* recursion depth */
00031 
00032 double  var = 0.3;                 /* variability */
00033 
00034 
00035 static void
00036 stick(mat, beg, end, rad)          /* output a branch or leaf */
00037 char  *mat;
00038 double  beg[3], end[3];
00039 double  rad;
00040 {
00041        static int  nsticks = 0;
00042        
00043        printf("\n%s cone s%d\n", mat, nsticks);
00044        printf("0\n0\n8\n");
00045        printf("\t%18.12g\t%18.12g\t%18.12g\n", beg[0], beg[1], beg[2]);
00046        printf("\t%18.12g\t%18.12g\t%18.12g\n", end[0], end[1], end[2]);
00047        printf("\t%18.12g\t%18.12g\n", rad, bnarrow*rad);
00048 
00049        printf("\n%s sphere e%d\n", mat, nsticks);
00050        printf("0\n0\n4");
00051        printf("\t%18.12g\t%18.12g\t%18.12g\t%18.12g\n",
00052                      end[0], end[1], end[2], bnarrow*rad);
00053 
00054        nsticks++;
00055 }
00056 
00057 
00058 static void
00059 branch(beg, end, rad, lvl)         /* generate branch recursively */
00060 double  beg[3], end[3];
00061 double  rad;
00062 int  lvl;
00063 {
00064        double  sqrt();
00065        double  newbeg[3], newend[3];
00066        double  t;
00067        int  i, j;
00068        
00069        if (lvl == 0) {
00070               stick(leafmat, beg, end, rad);
00071               return;
00072        }
00073 
00074        stick(branchmat, beg, end, rad);
00075 
00076        for (i = 1; i <= nshoots; i++) {
00077                                           /* right branch */
00078               t = (i+errf())/(nshoots+2);
00079               t = (t + sqrt(t))/2.0;
00080               for (j = 0; j < 3; j++) {
00081                      newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
00082                      newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
00083               }
00084               newend[0] += (end[2]-newbeg[2])*bratio*(1+errf());
00085               newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
00086               newend[2] -= (end[0]-newbeg[0])*bratio*(1+errf());
00087               branch(newbeg, newend,
00088                             (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
00089               
00090                                           /* left branch */
00091               t = (i+errf())/(nshoots+2);
00092               t = (t + sqrt(t))/2.0;
00093               for (j = 0; j < 3; j++) {
00094                      newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
00095                      newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
00096               }
00097               newend[0] -= (end[2]-newbeg[2])*bratio*(1+errf());
00098               newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
00099               newend[2] += (end[0]-newbeg[0])*bratio*(1+errf());
00100               branch(newbeg, newend,
00101                             (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
00102        }
00103 }
00104 
00105 
00106 void
00107 printhead(ac, av)           /* print command header */
00108 register int  ac;
00109 register char  **av;
00110 {
00111        putchar('#');
00112        while (ac--) {
00113               putchar(' ');
00114               fputs(*av++, stdout);
00115        }
00116        putchar('\n');
00117 }
00118 
00119 
00120 int
00121 main(argc, argv)
00122 int  argc;
00123 char  *argv[];
00124 {
00125        int  i, j;
00126 
00127        for (i = 1; i < argc && argv[i][0] == '-'; i++)
00128               switch (argv[i][1]) {
00129               case 'b':                   /* branch */
00130                      switch (argv[i][2]) {
00131                      case 's':                   /* start */
00132                             bstart[0] = atof(argv[++i]);
00133                             bstart[1] = atof(argv[++i]);
00134                             bstart[2] = atof(argv[++i]);
00135                             break;
00136                      case 'e':                   /* end */
00137                             bend[0] = atof(argv[++i]);
00138                             bend[1] = atof(argv[++i]);
00139                             bend[2] = atof(argv[++i]);
00140                             break;
00141                      case 't':                   /* thickness */
00142                             bthick = atof(argv[++i]);
00143                             break;
00144                      case 'n':                   /* narrow */
00145                             bnarrow = atof(argv[++i]);
00146                             break;
00147                      case 'r':                   /* ratio */
00148                             bratio = atof(argv[++i]);
00149                             break;
00150                      case 'm':                   /* material */
00151                             branchmat = argv[++i];
00152                             break;
00153                      default:
00154                             goto unkopt;
00155                      }
00156                      break;
00157               case 'l':                   /* leaf */
00158                      switch (argv[i][2]) {
00159                      case 'm':                   /* material */
00160                             leafmat = argv[++i];
00161                             break;
00162                      default:
00163                             goto unkopt;
00164                      }
00165                      break;
00166               case 'n':                   /* number of offshoots */
00167                      nshoots = atoi(argv[++i]);
00168                      break;
00169               case 'r':                   /* recursion depth */
00170                      rdepth = atoi(argv[++i]);
00171                      break;
00172               case 's':                   /* seed */
00173                      j = atoi(argv[++i]);
00174                      while (j-- > 0)
00175                             frandom();
00176                      break;
00177               case 'v':                   /* variability */
00178                      var = atof(argv[++i]);
00179                      break;
00180               default:;
00181 unkopt:                     fprintf(stderr, "%s: unknown option: %s\n",
00182                                    argv[0], argv[i]);
00183                      exit(1);
00184               }
00185        
00186        if (i != argc) {
00187               fprintf(stderr, "%s: bad argument\n", argv[0]);
00188               exit(1);
00189        }
00190        printhead(argc, argv);
00191 
00192        branch(bstart, bend, bthick, rdepth);
00193 
00194        return(0);
00195 }
00196