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