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

 
Output of file : RINGS.C contained in archive : PLYDAT.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. No object is clipped. Three light sources.
*
* Version: 2.2 (11/17/87)
* Author: Eric Haines, 3D/Eye, Inc.
*
* SIZE_FACTOR 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)
*
* SIZE_FACTOR # spheres # cylinders # squares
* 1 30 30 1
* 2 150 150 1
* 3 420 420 1
*
* 7 4200 4200 1
*/

#include
#include
#ifdef MAC
#include
#endif

#include "def.h"
#include "lib.h"

#define SIZE_FACTOR 2

/* 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 */
static void
create_dodec(double minor_radius, COORD4 vertex[30])
{
long num_vertex, num_pentagon ;
COORD4 temp_vertex ;
MATRIX x_matrix, z_matrix ;
double scale, x_rotation, z_rotation ;


/* 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_coord( &temp_vertex
, &vertex[num_vertex]
, x_matrix
) ;

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

void
main(int argc, char *argv[])
{
COORD4 base_pt, apex_pt, offset ;
COORD4 wall[4], dodec[30] ;
COORD4 from, at, up, dir;
COORD4 wvec, light ;
COORD4 back_color, ring_color[6] ;
long prev_elem ;
long num_elem ;
long num_depth, num_objx, num_objz ;
double radius ;
double spread, y_diff, xz_diff ;
char *txname, *c[6];
int cind = 0;

#ifdef MAC
argc = ccommand(&argv);
#endif


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_COORD( from, -1.0, -spread, 0.5 ) ;
SET_COORD( at, from.x, from.y + 1.0, from.z ) ;
SET_COORD( up, 0.0, 0.0, 1.0 ) ;
lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 256, 256);

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

/* output light source */
SET_COORD( light, 3.0, -spread, 3.0 ) ;
lib_output_light( &light ) ;
SET_COORD( light, -4.0, -spread, 1.0 ) ;
lib_output_light( &light ) ;
SET_COORD( light, 2.0, -spread, -4.0 ) ;
lib_output_light( &light ) ;

/* Output bounding slabs oriented along the coordinate axes */
SET_COORD(dir, 1.0, 0.0, 0.0);
lib_output_bounding_slab(&dir);
SET_COORD(dir, 0.0, 1.0, 0.0);
lib_output_bounding_slab(&dir);
SET_COORD(dir, 0.0, 0.0, 1.0);
lib_output_bounding_slab(&dir);

/* output wall polygon - white */
SET_COORD( back_color, 1.0, 1.0, 1.0 ) ;
txname = lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
/* just spans 45 degree view + 1% */
wvec.y = y_diff * ( SIZE_FACTOR + 1 ) ;
wvec.x = wvec.z = 1.01 * ( wvec.y - from.y ) * tan( PI / 8.0 ) ;
SET_COORD( wall[0], wvec.x+from.x, wvec.y, wvec.z+from.z ) ;
SET_COORD( wall[1], -wvec.x+from.x, wvec.y, wvec.z+from.z ) ;
SET_COORD( wall[2], -wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
SET_COORD( wall[3], wvec.x+from.x, wvec.y, -wvec.z+from.z ) ;
lib_output_polygon(4, wall, txname);

/* set up ring colors - RGB and complements */
SET_COORD(ring_color[0], 1.0, 0.0, 0.0);
SET_COORD(ring_color[1], 0.0, 1.0, 0.0);
SET_COORD(ring_color[2], 0.0, 0.0, 1.0);
SET_COORD(ring_color[3], 0.0, 1.0, 1.0);
SET_COORD(ring_color[4], 1.0, 0.0, 1.0);
SET_COORD(ring_color[5], 1.0, 1.0, 0.0);
c[0] = lib_output_color(&ring_color[0], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
c[1] = lib_output_color(&ring_color[1], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
c[2] = lib_output_color(&ring_color[2], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
c[3] = lib_output_color(&ring_color[3], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
c[4] = lib_output_color(&ring_color[4], 0.2, 0.5, 0.5, 10.0, 0.0, 0.0, 0.0);
c[5] = lib_output_color(&ring_color[5], 0.2, 0.5, 0.5, 10.0, 0.0, 0.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 < SIZE_FACTOR ; ++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 ) {
COPY_COORD( base_pt, dodec[num_elem] ) ;
ADD2_COORD( base_pt, offset ) ;
if ( num_elem%5 == 0 ) {
prev_elem = num_elem + 4 ;
/* new ring beginning - output color */
cind = num_elem/5;
}
else {
prev_elem = num_elem - 1 ;
}
COPY_COORD( apex_pt, dodec[prev_elem] ) ;
ADD2_COORD( apex_pt, offset ) ;

lib_output_cylcone( &base_pt, &apex_pt, c[cind]);
lib_output_sphere( &base_pt, c[cind]);
}
}
}
}
}


  3 Responses to “Category : Printer + Display Graphics
Archive   : PLYDAT.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/