home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gondwana.ecr.mu.oz.au/pub/
/
Graphics.tar
/
Graphics
/
SPD.3.0.shar.gz
/
SPD.3.0.shar
/
tree.c
< prev
Wrap
C/C++ Source or Header
|
1991-01-13
|
5KB
|
175 lines
/*
* tree.c - Creates a tree using Aono & Kunii's generation method.
* (See IEEE CG&A May 1984). A square polygon is placed beneath the
* tree to act as a field. Seven light sources.
*
* Author: Eric Haines, 3D/Eye, Inc.
*
* SizeFactor determines the number of objects output.
* Total objects = 2**(SF+1)-1 cones and spheres + 1 square polygon.
*
* SizeFactor # spheres # cones # squares
* 1 3 3 1
* 2 7 7 1
* 3 15 15 1
*
* 11 4095 4095 1
*/
#include <stdio.h>
#include <math.h>
#include "def.h"
#include "lib.h"
static int SizeFactor = 11 ;
#define OUTPUT_FORMAT OUTPUT_CURVES
/* the following affect the shape of the tree */
#define BR_ANGLE_0 40.0
#define BR_ANGLE_1 25.0
#define BR_CONTR_0 0.65
#define BR_CONTR_1 0.70
#define BR_DIAMETER 0.67
#define DIV_ANGLE 140.0
#define WIDTH_HEIGHTH_RATIO 0.15
static MATRIX Rst_mx[2] ;
main(argc,argv)
int argc ;
char *argv[] ;
{
COORD3 field[4] ;
COORD3 from, at, up ;
COORD3 light ;
COORD3 back_color, tree_color ;
if ( !lib_get_size( argc, argv, &SizeFactor ) ) {
fprintf( stderr, "usage: %s [size]\n", *argv ) ;
exit(EXIT_FAIL) ;
}
/* output viewpoint */
SET_COORD3( from, 4.5, 0.4, 2.0 ) ;
SET_COORD3( at, 0.0, 0.0, 1.5 ) ;
SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
lib_output_viewpoint( from, at, up, 45.0, 1.0, 512, 512 ) ;
/* output background color - UNC sky blue */
SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
lib_output_background_color( back_color ) ;
/* output light source */
SET_COORD3( light, -5.0, 5.0, 50.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, 30.0, -30.0, 30.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, -40.0, -30.0, 20.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, 10.0, 30.0, 40.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, -30.0, 40.0, 10.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, 50.0, 25.0, 20.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, -10.0, -60.0, 30.0 ) ;
lib_output_light( light ) ;
/* output field polygon - green */
SET_COORD3( back_color, 0.2, 0.7, 0.2 ) ;
lib_output_color( back_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
SET_COORD3( field[0], 50.0, 50.0, 0.0 ) ;
SET_COORD3( field[1], -50.0, 50.0, 0.0 ) ;
SET_COORD3( field[2], -50.0, -50.0, 0.0 ) ;
SET_COORD3( field[3], 50.0, -50.0, 0.0 ) ;
lib_output_polygon( 4, field ) ;
/* set up tree color - brown */
SET_COORD3( tree_color, 0.55, 0.4, 0.2 ) ;
lib_output_color( tree_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
/* create tree */
create_tree() ;
exit(EXIT_SUCCESS) ;
}
/*
* Set up matrices for growth of each branch with respect to the
* parent branch, then grow each branch.
*/
create_tree()
{
int i ;
double branch_angle, branch_contraction, divergence ;
MATRIX ident_mx, temp1_mx, temp2_mx, tempr_mx, tempst_mx ;
for ( i = 0 ; i < 2 ; ++i ) {
if ( i == 0 ) {
branch_angle = BR_ANGLE_0 ;
divergence = 90.0 ;
branch_contraction = BR_CONTR_0 ;
}
else {
branch_angle = BR_ANGLE_1 ;
divergence = DIV_ANGLE + 90.0 ;
branch_contraction = BR_CONTR_1 ;
}
/* rotate along X axis by branching angle */
lib_create_rotate_matrix( temp1_mx, X_AXIS, branch_angle*PI/180.0 ) ;
/* rotate along Z axis by divergence angle */
lib_create_rotate_matrix( temp2_mx, Z_AXIS, divergence*PI/180.0 ) ;
lib_matrix_multiply( tempr_mx, temp1_mx, temp2_mx ) ;
/* include translation of branch, scaled */
lib_create_identity_matrix( tempst_mx ) ;
tempst_mx[0][0] = tempst_mx[1][1] = tempst_mx[2][2] =
branch_contraction ;
tempst_mx[3][2] = 1.0 ;
/* concatenate */
lib_matrix_multiply( Rst_mx[i], tempr_mx, tempst_mx ) ;
}
/* set up initial matrix */
lib_create_identity_matrix( ident_mx ) ;
grow_tree( ident_mx, 1.0, SizeFactor ) ;
}
/* grow tree branches recursively */
grow_tree( cur_mx, scale, depth )
MATRIX cur_mx ;
double scale ;
int depth ;
{
int i ;
COORD3 vec ;
COORD4 apex, base ;
MATRIX new_mx ;
/* output branch */
SET_COORD3( vec, 0.0, 0.0, 0.0 ) ;
lib_transform_point( base, vec, cur_mx ) ;
base[W] = scale * WIDTH_HEIGHTH_RATIO ;
SET_COORD3( vec, 0.0, 0.0, 1.0 ) ;
lib_transform_point( apex, vec, cur_mx ) ;
apex[W] = base[W] * BR_DIAMETER ;
lib_output_cylcone( base, apex, OUTPUT_FORMAT ) ;
lib_output_sphere( apex, OUTPUT_FORMAT ) ;
if ( depth > 0 ) {
--depth ;
for ( i = 0 ; i < 2 ; ++i ) {
lib_matrix_multiply( new_mx, Rst_mx[i], cur_mx ) ;
grow_tree( new_mx, scale * BR_DIAMETER, depth ) ;
}
}
}