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
/
balls.c
next >
Wrap
C/C++ Source or Header
|
1991-01-13
|
5KB
|
182 lines
/*
* balls.c - Also known as "sphereflake". Create a set of shiny spheres, with
* each sphere blooming sets of 9 more spheres with 1/3rd radius.
* A square floor polygon is added. Three light sources.
*
* Author: Eric Haines, 3D/Eye, Inc.
*
* SizeFactor determines the number of objects output.
* Total spheres = sum of n=0,SF of (9**SF).
*
* SizeFactor # spheres # squares
* 1 10 1
* 2 91 1
* 3 820 1
*
* 4 7381 1
*/
#include <stdio.h>
#include <math.h>
#include "def.h"
#include "lib.h"
static int SizeFactor = 4 ;
#define OUTPUT_FORMAT OUTPUT_CURVES
/* radius of sphere enclosing all balls (a scale factor) */
#define BV_RADIUS 1.0
main(argc,argv)
int argc ;
char *argv[] ;
{
COORD3 back_color, obj_color ;
COORD3 from, at, up ;
COORD3 ground[4], bvec, light, objset[9] ;
COORD4 center_pt, direction ;
if ( !lib_get_size( argc, argv, &SizeFactor ) ) {
fprintf( stderr, "usage: %s [size]\n", *argv ) ;
exit(EXIT_FAIL) ;
}
/* output viewpoint */
SET_COORD3( from, 2.1, 1.3, 1.7 ) ;
SET_COORD3( at, 0.0, 0.0, 0.0 ) ;
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 sources */
SET_COORD3( light, 4.0, 3.0, 2.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, 1.0, -4.0, 4.0 ) ;
lib_output_light( light ) ;
SET_COORD3( light, -3.0, 1.0, 5.0 ) ;
lib_output_light( light ) ;
/* output floor polygon - beige */
SET_COORD3( back_color, 1.0, 0.75, 0.33 ) ;
lib_output_color( back_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
SET_COORD3( bvec, 12.0 * BV_RADIUS, 12.0 * BV_RADIUS, -BV_RADIUS / 2.0 ) ;
SET_COORD3( ground[0], bvec[X], bvec[Y], bvec[Z] ) ;
SET_COORD3( ground[1], -bvec[X], bvec[Y], bvec[Z] ) ;
SET_COORD3( ground[2], -bvec[X], -bvec[Y], bvec[Z] ) ;
SET_COORD3( ground[3], bvec[X], -bvec[Y], bvec[Z] ) ;
lib_output_polygon( 4, ground ) ;
/* set up object color - off white */
SET_COORD3( obj_color, 1.0, 0.9, 0.7 ) ;
lib_output_color( obj_color, 0.5, 0.5, 3.0, 0.0, 0.0 ) ;
/* create set of spawned points */
create_objset( objset ) ;
/* compute and output object */
SET_COORD4( center_pt, 0.0, 0.0, 0.0, BV_RADIUS / 2.0 ) ;
SET_COORD4( direction, 0.0, 0.0, 1.0, 1.0/3.0 ) ;
output_object( SizeFactor, center_pt, direction, objset ) ;
exit(EXIT_SUCCESS) ;
}
/* Create the set of 9 vectors needed to generate the sphere set. */
create_objset( objset )
COORD3 objset[9] ;
{
int num_set, num_vert ;
double dist ;
COORD3 axis, temp_pt, trio_dir[3] ;
MATRIX mx ;
dist = 1.0 / sqrt( (double)2.0 ) ;
SET_COORD3( trio_dir[0], dist, dist, 0.0 ) ;
SET_COORD3( trio_dir[1], dist, 0.0, -dist ) ;
SET_COORD3( trio_dir[2], 0.0, dist, -dist ) ;
SET_COORD3( axis, 1.0, -1.0, 0.0 ) ;
(void)lib_normalize_vector( axis ) ;
lib_create_axis_rotate_matrix(
mx
, axis
, asin( (double) ( 2.0 / sqrt( (double)6.0 ) ) ) ) ;
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
lib_transform_vector( temp_pt, trio_dir[num_vert], mx ) ;
COPY_COORD3( trio_dir[num_vert], temp_pt ) ;
}
for ( num_set = 0 ; num_set < 3 ; ++num_set ) {
lib_create_rotate_matrix( mx, Z_AXIS, num_set*2.0*PI/3.0 ) ;
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
lib_transform_vector( objset[num_set*3+num_vert],
trio_dir[num_vert], mx ) ;
}
}
}
/*
* Output the parent sphere, then output the children of the sphere.
*/
output_object( depth, center, direction, objset )
int depth ;
COORD4 center ;
COORD4 direction ;
COORD3 objset[9] ;
{
int num_vert ;
double angle, scale ;
COORD3 axis, z_axis ;
COORD4 child_pt, child_dir ;
MATRIX mx ;
/* output sphere at location & radius defined by center */
lib_output_sphere( center, OUTPUT_FORMAT ) ;
/* check if children should be generated */
if ( depth > 0 ) {
--depth ;
/* rotation matrix to new axis from +Z axis */
if ( direction[Z] >= 1.0 ) {
/* identity matrix */
lib_create_identity_matrix( mx ) ;
}
else if ( direction[Z] <= -1.0 ) {
lib_create_rotate_matrix( mx, Y_AXIS, PI ) ;
}
else {
SET_COORD3( z_axis, 0.0, 0.0, 1.0 ) ;
CROSS( axis, z_axis, direction ) ;
(void)lib_normalize_vector( axis ) ;
angle = acos( (double)DOT_PRODUCT( z_axis, direction ) ) ;
lib_create_axis_rotate_matrix( mx, axis, angle ) ;
}
/* scale down location of new spheres */
scale = center[W] * (1.0 + direction[W] ) ;
for ( num_vert = 0 ; num_vert < 9 ; ++num_vert ) {
lib_transform_vector( child_pt, objset[num_vert], mx ) ;
child_pt[X] = child_pt[X] * scale + center[X] ;
child_pt[Y] = child_pt[Y] * scale + center[Y] ;
child_pt[Z] = child_pt[Z] * scale + center[Z] ;
/* scale down radius */
child_pt[W] = center[W] * direction[W] ;
SUB3_COORD3( child_dir, child_pt, center ) ;
child_dir[X] /= scale ;
child_dir[Y] /= scale ;
child_dir[Z] /= scale ;
child_dir[W] = direction[W] ;
output_object( depth, child_pt, child_dir, objset ) ;
}
}
}