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

  1. /* Copyright (c) 1989 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)genbranch.c 2.2 12/19/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  genbranch.c - program to generate 3D Christmas tree branches.
  9.  *
  10.  *     8/23/86
  11.  */
  12.  
  13. #include  <stdio.h>
  14.  
  15. #include  "random.h"
  16.  
  17. #define  errf()        (var*(0.5-frandom()))
  18.  
  19. #ifndef atof
  20. extern double  atof();
  21. #endif
  22.  
  23. double  bstart[3] = {0.0, 0.0, 0.0};    /* start of branch */
  24. double  bend[3] = {28.0, 8.0, 0.0};    /* end of branch */
  25. double  bthick = .6;            /* branch radius at base */
  26. double  bnarrow = .4;            /* ratio of tip radius to base */
  27. double  bratio = .4;            /* ratio of limb to branch */
  28. char  *branchmat = "m_bark";        /* bark material */
  29.  
  30. char  *leafmat = "m_leaf";        /* leaf material */
  31.  
  32. int  nshoots = 7;            /* number of offshoots */
  33. int  rdepth = 3;            /* recursion depth */
  34.  
  35. double  var = 0.3;            /* variability */
  36.  
  37.  
  38. main(argc, argv)
  39. int  argc;
  40. char  *argv[];
  41. {
  42.     int  i, j;
  43.  
  44.     for (i = 1; i < argc && argv[i][0] == '-'; i++)
  45.         switch (argv[i][1]) {
  46.         case 'b':            /* branch */
  47.             switch (argv[i][2]) {
  48.             case 's':            /* start */
  49.                 bstart[0] = atof(argv[++i]);
  50.                 bstart[1] = atof(argv[++i]);
  51.                 bstart[2] = atof(argv[++i]);
  52.                 break;
  53.             case 'e':            /* end */
  54.                 bend[0] = atof(argv[++i]);
  55.                 bend[1] = atof(argv[++i]);
  56.                 bend[2] = atof(argv[++i]);
  57.                 break;
  58.             case 't':            /* thickness */
  59.                 bthick = atof(argv[++i]);
  60.                 break;
  61.             case 'n':            /* narrow */
  62.                 bnarrow = atof(argv[++i]);
  63.                 break;
  64.             case 'r':            /* ratio */
  65.                 bratio = atof(argv[++i]);
  66.                 break;
  67.             case 'm':            /* material */
  68.                 branchmat = argv[++i];
  69.                 break;
  70.             default:
  71.                 goto unkopt;
  72.             }
  73.             break;
  74.         case 'l':            /* leaf */
  75.             switch (argv[i][2]) {
  76.             case 'm':            /* material */
  77.                 leafmat = argv[++i];
  78.                 break;
  79.             default:
  80.                 goto unkopt;
  81.             }
  82.             break;
  83.         case 'n':            /* number of offshoots */
  84.             nshoots = atoi(argv[++i]);
  85.             break;
  86.         case 'r':            /* recursion depth */
  87.             rdepth = atoi(argv[++i]);
  88.             break;
  89.         case 's':            /* seed */
  90.             j = atoi(argv[++i]);
  91.             while (j-- > 0)
  92.                 frandom();
  93.             break;
  94.         case 'v':            /* variability */
  95.             var = atof(argv[++i]);
  96.             break;
  97.         default:;
  98. unkopt:            fprintf(stderr, "%s: unknown option: %s\n",
  99.                     argv[0], argv[i]);
  100.             exit(1);
  101.         }
  102.     
  103.     if (i != argc) {
  104.         fprintf(stderr, "%s: bad argument\n", argv[0]);
  105.         exit(1);
  106.     }
  107.     printhead(argc, argv);
  108.  
  109.     branch(bstart, bend, bthick, rdepth);
  110.  
  111.     return(0);
  112. }
  113.  
  114.  
  115. branch(beg, end, rad, lvl)        /* generate branch recursively */
  116. double  beg[3], end[3];
  117. double  rad;
  118. int  lvl;
  119. {
  120.     double  sqrt();
  121.     double  newbeg[3], newend[3];
  122.     double  t;
  123.     int  i, j;
  124.     
  125.     if (lvl == 0) {
  126.         stick(leafmat, beg, end, rad);
  127.         return;
  128.     }
  129.  
  130.     stick(branchmat, beg, end, rad);
  131.  
  132.     for (i = 1; i <= nshoots; i++) {
  133.                         /* right branch */
  134.         t = (i+errf())/(nshoots+2);
  135.         t = (t + sqrt(t))/2.0;
  136.         for (j = 0; j < 3; j++) {
  137.             newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
  138.             newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
  139.         }
  140.         newend[0] += (end[2]-newbeg[2])*bratio*(1+errf());
  141.         newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
  142.         newend[2] -= (end[0]-newbeg[0])*bratio*(1+errf());
  143.         branch(newbeg, newend,
  144.                 (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
  145.         
  146.                         /* left branch */
  147.         t = (i+errf())/(nshoots+2);
  148.         t = (t + sqrt(t))/2.0;
  149.         for (j = 0; j < 3; j++) {
  150.             newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
  151.             newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
  152.         }
  153.         newend[0] -= (end[2]-newbeg[2])*bratio*(1+errf());
  154.         newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
  155.         newend[2] += (end[0]-newbeg[0])*bratio*(1+errf());
  156.         branch(newbeg, newend,
  157.                 (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
  158.     }
  159. }
  160.  
  161.  
  162. stick(mat, beg, end, rad)        /* output a branch or leaf */
  163. char  *mat;
  164. double  beg[3], end[3];
  165. double  rad;
  166. {
  167.     static int  nsticks = 0;
  168.     
  169.     printf("\n%s cone s%d\n", mat, nsticks);
  170.     printf("0\n0\n8\n");
  171.     printf("\t%18.12g\t%18.12g\t%18.12g\n", beg[0], beg[1], beg[2]);
  172.     printf("\t%18.12g\t%18.12g\t%18.12g\n", end[0], end[1], end[2]);
  173.     printf("\t%18.12g\t%18.12g\n", rad, bnarrow*rad);
  174.  
  175.     printf("\n%s sphere e%d\n", mat, nsticks);
  176.     printf("0\n0\n4");
  177.     printf("\t%18.12g\t%18.12g\t%18.12g\%18.12g\n",
  178.             end[0], end[1], end[2], bnarrow*rad);
  179.  
  180.     nsticks++;
  181. }
  182.  
  183.  
  184. printhead(ac, av)        /* print command header */
  185. register int  ac;
  186. register char  **av;
  187. {
  188.     putchar('#');
  189.     while (ac--) {
  190.         putchar(' ');
  191.         fputs(*av++, stdout);
  192.     }
  193.     putchar('\n');
  194. }
  195.