Category : Printer + Display Graphics
Archive   : PLYDAT16.ZIP
Filename : RINGS.C

 
Output of file : RINGS.C contained in archive : PLYDAT16.ZIP
/*
* rings.c - Create objects with 6 pentagonal rings which connect the midpoints
* of the edges of a dodecahedron. A pyramid of these objects is formed,
* which the viewer looks upon from the point. A plane is placed behind
* the pyramid for shadows. Three light sources.
*
* Author: Eric Haines, 3D/Eye, Inc.
*
* SizeFactor determines the number of objects output.
* Each object has 30 cylinders and 30 spheres.
* Total objects = SF*SF + (SF-1)*(SF-1) + ... + 1 plus 1 backdrop square.
* formula for # of spheres or cylinders = 5*SF*(SF+1)*(2*SF+1)
*
* SizeFactor # spheres # cylinders # squares
* 1 30 30 1
* 2 150 150 1
* 3 420 420 1
*
* 7 4200 4200 1
*/

#include
#include
#include /* atoi */
#include "def.h"
#include "disp.h" /* display_close() */
#include "lib.h"

static int SizeFactor = 7 ;
static int raytracer_format = OUTPUT_RT_DEFAULT;
static int output_format = OUTPUT_CURVES;

#ifdef OUTPUT_TO_FILE
static FILE * stdout_file = NULL;
#else
#define stdout_file stdout
#endif OUTPUT_TO_FILE

/* if spread out is > 1, succeeding layers spread out more */
#define SPREAD_OUT 1

/* Create the set of 30 points needed to generate the rings */
void
create_dodec( minor_radius, vertex )
double minor_radius ;
COORD3 vertex[30] ;
{
int num_vertex, num_pentagon ;
double scale, x_rotation, z_rotation ;
COORD3 temp_vertex ;
MATRIX x_matrix, z_matrix ;

/* scale object to fit in a sphere of radius 1 */
scale = 1.0 / ( 1.0 + minor_radius ) ;

/*
* define one pentagon as on the XY plane, with points starting along +X
* and N fifths of the way around the Z axis.
*/
for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {
vertex[num_vertex][X] = scale * cos((double)num_vertex * 2.0*PI/5.0 ) ;
vertex[num_vertex][Y] = scale * sin((double)num_vertex * 2.0*PI/5.0 ) ;
vertex[num_vertex][Z] = 0.0 ;
vertex[num_vertex][W] = 1.0 ;
}

/*
* find the rotation angle (in radians) along the X axis:
* angle between two adjacent dodecahedron faces.
*/
x_rotation = 2.0 *
acos( cos( (double)(PI/3.0) ) / sin( (double)(PI/5.0) ) ) ;
lib_create_rotate_matrix( x_matrix, X_AXIS, x_rotation ) ;

/*
* Find each of the other 5 pentagons: rotate along the X axis,
* then rotate on the Z axis.
*/
for ( num_pentagon = 1 ; num_pentagon < 6 ; ++num_pentagon ) {
/*
* find the rotation angle (in radians) along the Z axis:
* 1/10th plus N fifths of the way around * 2 * PI.
*/
z_rotation = PI*( 2.0*(double)(num_pentagon-1)+1.0 ) / 5.0 ;
lib_create_rotate_matrix( z_matrix, Z_AXIS, z_rotation ) ;

for ( num_vertex = 0 ; num_vertex < 5 ; ++num_vertex ) {

lib_transform_point( temp_vertex
, vertex[num_vertex]
, x_matrix
) ;

lib_transform_point( vertex[5*num_pentagon+num_vertex]
, temp_vertex
, z_matrix
) ;
}
}
}

int
main(argc,argv)
int argc;
char *argv[];
{
int prev_elem, num_elem, num_depth, num_objx, num_objz ;
double radius, spread, y_diff, xz_diff ;
COORD4 base_pt, apex_pt ;
COORD3 from, at, up ;
COORD3 wvec, light ;
COORD3 back_color, ring_color[6] ;
COORD3 wall[4], offset, dodec[30] ;
double lscale;

PLATFORM_INIT(SPD_RINGS);

/* Start by defining which raytracer we will be using */
switch (argc) {
case 4:
output_format = atoi(argv[3]);
case 3:
raytracer_format = atoi(argv[2]);
case 2:
SizeFactor = atoi(argv[1]);
break;
defaut:
break;
}
#ifdef OUTPUT_TO_FILE
/* no stdout, so write to a file! */
if (raytracer_format != OUTPUT_VIDEO)
stdout_file = fopen("Rings.out","w");
#endif OUTPUT_TO_FILE
lib_set_output_file(stdout_file);

if (raytracer_format == OUTPUT_RTRACE ||
raytracer_format == OUTPUT_PLG)
lib_set_raytracer(OUTPUT_DELAYED);
else
lib_set_raytracer(raytracer_format);

radius = 0.07412 ; /* cone and sphere radius */

/* calculate spread of objects */
spread = 1 / sin( (double)( PI/8.0 ) ) ;
if ( SPREAD_OUT <= spread ) {
y_diff = spread / SPREAD_OUT ;
xz_diff = 1.0 ;
}
else {
y_diff = 1.0 ;
xz_diff = SPREAD_OUT / spread ;
}

/* output viewpoint */
SET_COORD3( from, -1.0, -spread, 0.5 ) ;
SET_COORD3( at, from[X], from[Y] + 1.0, from[Z] ) ;
SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
lib_output_viewpoint( from, at, up, 45.0, 1.0, 1.0, 512, 512);

/* output background color - UNC sky blue */
/* note that the background color should never be seen */
SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
lib_output_background_color( back_color ) ;

/* output light source */
lscale = (raytracer_format == OUTPUT_NFF ||
raytracer_format == OUTPUT_RTRACE ? 1.0 : 1.0/sqrt(3.0));
SET_COORD4( light, 3.0, -spread, 3.0, lscale ) ;
lib_output_light( light ) ;
SET_COORD4( light, -4.0, -spread, 1.0, lscale ) ;
lib_output_light( light ) ;
SET_COORD4( light, 2.0, -spread, -4.0, lscale ) ;
lib_output_light( light ) ;

/* output wall polygon - white */
SET_COORD3( back_color, 1.0, 1.0, 1.0 ) ;
lib_output_color(NULL, back_color, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);

/* just spans 45 degree view + 1% */
wvec[Y] = y_diff * ( SizeFactor + 1 ) ;
wvec[X] = wvec[Z] = 1.01 * ( wvec[Y] - from[Y] ) * tan( PI / 8.0 ) ;
SET_COORD3( wall[0], wvec[X]+from[X], wvec[Y], wvec[Z]+from[Z] ) ;
SET_COORD3( wall[1], -wvec[X]+from[X], wvec[Y], wvec[Z]+from[Z] ) ;
SET_COORD3( wall[2], -wvec[X]+from[X], wvec[Y], -wvec[Z]+from[Z] ) ;
SET_COORD3( wall[3], wvec[X]+from[X], wvec[Y], -wvec[Z]+from[Z] ) ;
lib_output_polygon( 4, wall ) ;

/* set up ring colors - RGB and complements */
SET_COORD3( ring_color[0], 1.0, 0.0, 0.0 ) ;
SET_COORD3( ring_color[1], 0.0, 1.0, 0.0 ) ;
SET_COORD3( ring_color[2], 0.0, 0.0, 1.0 ) ;
SET_COORD3( ring_color[3], 0.0, 1.0, 1.0 ) ;
SET_COORD3( ring_color[4], 1.0, 0.0, 1.0 ) ;
SET_COORD3( ring_color[5], 1.0, 1.0, 0.0 ) ;

create_dodec( radius, dodec ) ;
/* radius of osculating cylinders and spheres (no derivation given) */
base_pt[W] = apex_pt[W] = radius ;

for ( num_depth = 0 ; num_depth < SizeFactor ; ++num_depth ) {
offset[Y] = y_diff * (double)(num_depth+1) ;
for ( num_objz = 0 ; num_objz <= num_depth ; ++num_objz ) {
offset[Z] = xz_diff * (double)(2*num_objz - num_depth) ;
for ( num_objx = 0 ; num_objx <= num_depth ; ++num_objx ) {
offset[X] = xz_diff * (double)(2*num_objx - num_depth) ;
for ( num_elem = 0 ; num_elem < 30 ; ++num_elem ) {
PLATFORM_MULTITASK();
COPY_COORD3( base_pt, dodec[num_elem] ) ;
ADD2_COORD3( base_pt, offset ) ;
if ( num_elem%5 == 0 ) {
prev_elem = num_elem + 4 ;
/* new ring beginning - output color */
lib_output_color(NULL, ring_color[num_elem/5],
0.0, 0.5, 0.2, 0.3, 10.0, 0.0, 0.0);
}
else {
prev_elem = num_elem - 1 ;
}
COPY_COORD3( apex_pt, dodec[prev_elem] ) ;
ADD2_COORD3( apex_pt, offset ) ;

lib_output_cylcone( base_pt, apex_pt, output_format ) ;
lib_output_sphere( base_pt, output_format ) ;
}
}
}
}

/* Make sure everything is cleaned up */
if (raytracer_format == OUTPUT_RTRACE ||
raytracer_format == OUTPUT_PLG) {
lib_set_raytracer(raytracer_format);
lib_flush_definitions();
}
#ifdef OUTPUT_TO_FILE
/* no stdout, so close our output! */
if (stdout_file)
fclose(stdout_file);
#endif OUTPUT_TO_FILE
if (raytracer_format == OUTPUT_VIDEO)
display_close(1);

PLATFORM_SHUTDOWN();
return EXIT_SUCCESS ;
}



  3 Responses to “Category : Printer + Display Graphics
Archive   : PLYDAT16.ZIP
Filename : RINGS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/