home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
p
/
ply15dat.zip
/
TREE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-19
|
5KB
|
163 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. No tree branch is clipped. Seven light sources.
*
* Version: 2.2 (11/17/87)
* Author: Eric Haines, 3D/Eye, Inc.
*
* SIZE_FACTOR determines the number of objects output.
* Total objects = 2**(SF+1)-1 cones and spheres + 1 square polygon.
*
* SIZE_FACTOR # 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"
#define OUTPUT_FORMAT OUTPUT_CURVES
#define SIZE_FACTOR 9
/* 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] ;
/* grow tree branches recursively */
static void
grow_tree(MATRIX cur_mx, double scale, long depth)
{
COORD4 apex, base, vec ;
long i ;
MATRIX new_mx ;
/* output branch */
SET_COORD4( vec, 0.0, 0.0, 0.0, 1.0 ) ;
lib_transform_coord( &base, &vec, cur_mx ) ;
base.w = scale * WIDTH_HEIGHTH_RATIO ;
SET_COORD4( vec, 0.0, 0.0, 1.0, 1.0 ) ;
lib_transform_coord( &apex, &vec, cur_mx ) ;
apex.w = base.w * BR_DIAMETER ;
lib_output_cylcone( &base, &apex, OUTPUT_CURVES ) ;
lib_output_sphere( &apex, OUTPUT_CURVES ) ;
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);
}
}
}
/*
* Set up matrices for growth of each branch with respect to the
* parent branch, then grow each branch.
*/
static void
create_tree()
{
double branch_angle, branch_contraction, divergence ;
long i ;
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, SIZE_FACTOR);
}
void
main(int argc, char *argv[])
{
COORD4 field[4] ;
COORD4 from, at, up, dir;
COORD4 light ;
COORD4 back_color, tree_color ;
/* We are using Polyray */
lib_set_raytracer(OUTPUT_POLYRAY);
/* output viewpoint */
SET_COORD( from, 4.5, 0.4, 2.0 ) ;
SET_COORD( at, 0.0, 0.0, 1.5 ) ;
SET_COORD( up, 0.0, 0.0, 1.0 ) ;
lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
/* output background color - UNC sky blue */
SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
lib_output_background_color( &back_color ) ;
/* output light sources */
SET_COORD4( light, 10.0, 30.0, 40.0, 0.6 ) ;
lib_output_light( &light ) ;
SET_COORD4( light, -30.0, 40.0, 10.0, 0.6 ) ;
lib_output_light( &light ) ;
SET_COORD4( light, 50.0, 25.0, 20.0, 0.6 ) ;
lib_output_light( &light ) ;
/* output field polygon - green */
SET_COORD( back_color, 0.2, 0.7, 0.2 ) ;
lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0) ;
SET_COORD( field[0], 50.0, 50.0, 0.0 ) ;
SET_COORD( field[1], -50.0, 50.0, 0.0 ) ;
SET_COORD( field[2], -50.0, -50.0, 0.0 ) ;
SET_COORD( field[3], 50.0, -50.0, 0.0 ) ;
lib_output_polygon(4, field);
/* set up tree color - brown */
SET_COORD( tree_color, 0.55, 0.4, 0.2 ) ;
lib_output_color( &tree_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
/* create tree */
create_tree();
}