home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1989 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)genbranch.c 2.2 12/19/91 LBL";
- #endif
-
- /*
- * genbranch.c - program to generate 3D Christmas tree branches.
- *
- * 8/23/86
- */
-
- #include <stdio.h>
-
- #include "random.h"
-
- #define errf() (var*(0.5-frandom()))
-
- #ifndef atof
- extern double atof();
- #endif
-
- double bstart[3] = {0.0, 0.0, 0.0}; /* start of branch */
- double bend[3] = {28.0, 8.0, 0.0}; /* end of branch */
- double bthick = .6; /* branch radius at base */
- double bnarrow = .4; /* ratio of tip radius to base */
- double bratio = .4; /* ratio of limb to branch */
- char *branchmat = "m_bark"; /* bark material */
-
- char *leafmat = "m_leaf"; /* leaf material */
-
- int nshoots = 7; /* number of offshoots */
- int rdepth = 3; /* recursion depth */
-
- double var = 0.3; /* variability */
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i, j;
-
- for (i = 1; i < argc && argv[i][0] == '-'; i++)
- switch (argv[i][1]) {
- case 'b': /* branch */
- switch (argv[i][2]) {
- case 's': /* start */
- bstart[0] = atof(argv[++i]);
- bstart[1] = atof(argv[++i]);
- bstart[2] = atof(argv[++i]);
- break;
- case 'e': /* end */
- bend[0] = atof(argv[++i]);
- bend[1] = atof(argv[++i]);
- bend[2] = atof(argv[++i]);
- break;
- case 't': /* thickness */
- bthick = atof(argv[++i]);
- break;
- case 'n': /* narrow */
- bnarrow = atof(argv[++i]);
- break;
- case 'r': /* ratio */
- bratio = atof(argv[++i]);
- break;
- case 'm': /* material */
- branchmat = argv[++i];
- break;
- default:
- goto unkopt;
- }
- break;
- case 'l': /* leaf */
- switch (argv[i][2]) {
- case 'm': /* material */
- leafmat = argv[++i];
- break;
- default:
- goto unkopt;
- }
- break;
- case 'n': /* number of offshoots */
- nshoots = atoi(argv[++i]);
- break;
- case 'r': /* recursion depth */
- rdepth = atoi(argv[++i]);
- break;
- case 's': /* seed */
- j = atoi(argv[++i]);
- while (j-- > 0)
- frandom();
- break;
- case 'v': /* variability */
- var = atof(argv[++i]);
- break;
- default:;
- unkopt: fprintf(stderr, "%s: unknown option: %s\n",
- argv[0], argv[i]);
- exit(1);
- }
-
- if (i != argc) {
- fprintf(stderr, "%s: bad argument\n", argv[0]);
- exit(1);
- }
- printhead(argc, argv);
-
- branch(bstart, bend, bthick, rdepth);
-
- return(0);
- }
-
-
- branch(beg, end, rad, lvl) /* generate branch recursively */
- double beg[3], end[3];
- double rad;
- int lvl;
- {
- double sqrt();
- double newbeg[3], newend[3];
- double t;
- int i, j;
-
- if (lvl == 0) {
- stick(leafmat, beg, end, rad);
- return;
- }
-
- stick(branchmat, beg, end, rad);
-
- for (i = 1; i <= nshoots; i++) {
- /* right branch */
- t = (i+errf())/(nshoots+2);
- t = (t + sqrt(t))/2.0;
- for (j = 0; j < 3; j++) {
- newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
- newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
- }
- newend[0] += (end[2]-newbeg[2])*bratio*(1+errf());
- newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
- newend[2] -= (end[0]-newbeg[0])*bratio*(1+errf());
- branch(newbeg, newend,
- (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
-
- /* left branch */
- t = (i+errf())/(nshoots+2);
- t = (t + sqrt(t))/2.0;
- for (j = 0; j < 3; j++) {
- newbeg[j] = newend[j] = (end[j]-beg[j])*t + beg[j];
- newend[j] += (end[j]-beg[j])*(1+errf())/(nshoots+2);
- }
- newend[0] -= (end[2]-newbeg[2])*bratio*(1+errf());
- newend[1] += (end[1]-newbeg[1])*bratio*(1+errf());
- newend[2] += (end[0]-newbeg[0])*bratio*(1+errf());
- branch(newbeg, newend,
- (1-(1-bnarrow)*t)*(1+2*bratio)/3*rad, lvl-1);
- }
- }
-
-
- stick(mat, beg, end, rad) /* output a branch or leaf */
- char *mat;
- double beg[3], end[3];
- double rad;
- {
- static int nsticks = 0;
-
- printf("\n%s cone s%d\n", mat, nsticks);
- printf("0\n0\n8\n");
- printf("\t%18.12g\t%18.12g\t%18.12g\n", beg[0], beg[1], beg[2]);
- printf("\t%18.12g\t%18.12g\t%18.12g\n", end[0], end[1], end[2]);
- printf("\t%18.12g\t%18.12g\n", rad, bnarrow*rad);
-
- printf("\n%s sphere e%d\n", mat, nsticks);
- printf("0\n0\n4");
- printf("\t%18.12g\t%18.12g\t%18.12g\%18.12g\n",
- end[0], end[1], end[2], bnarrow*rad);
-
- nsticks++;
- }
-
-
- printhead(ac, av) /* print command header */
- register int ac;
- register char **av;
- {
- putchar('#');
- while (ac--) {
- putchar(' ');
- fputs(*av++, stdout);
- }
- putchar('\n');
- }
-