
#include <stdio.h>
#include <math.h>

#define PI 3.14159


int
main( argc, argv, envp )
int argc;
char * argv[];
char * envp[];
{
	float x0 = -PI / 2.0;       /* Starting function evaluation X bound   */
	float x1 = +PI / 2.0;       /* Ending function evaluation X bound     */
	float y0 = -PI / 2.0;       /* Starting function evaluation Y bound   */
	float y1 = +PI / 2.0;       /* Ending function evaluation Y bound     */
	float z0 = -PI / 2.0;       /* Starting function evaluation Z bound   */
	float z1 = +PI / 2.0;       /* Ending function evaluation Z bound     */
	float x;                    /* Current function evaluation point      */
	float y;                    /* Current function evaluation point      */
	float z;                    /* Current function evaluation point      */
	float s = 4.0;              /* Position scale (makes it look nice)    */
	float xstep = (x1-x0)/6.0;  /* Step size in X dimension               */
	float ystep = (y1-y0)/6.0;  /* Step size in Y dimension               */
	float zstep = (z1-z0)/6.0;  /* Step size in Z dimension               */
	float cross[3];             /* Cross product of (rotation vector)     */
	float clen;                 /* Length of cross product                */
	float theta;                /* Angle between point and +y axis        */
	float color[3];             /* RGB color of current vector            */
	float phase[3];             /* Phase shift for bounds                 */
	float pc;                   /* Phase change value (cmd line option)   */

	/* See if the user has supplied a PHASE CHANGE command line argument */

	if ( argc == 1 ) {
		pc = 0.0;
	} else if ( argc == 2 ) {
		pc = atof( argv[1] );
	} else {
		fprintf( stderr, "Invalid command line.\n" );
		fprintf( stderr, "Usage:  %s [phase]\n", argv[0] );
		exit( 0 );
	}

	phase[0] = 0.0 + pc;
	phase[1] = PI / 2.0 + pc;
	phase[2] = PI + pc;

	/* Output a VRML header */

	printf( "#VRML V2.0 utf8\n" );
	printf( "# Phase Change = %f\n", pc );
	printf( "\n" );

	/* Declare the Vector EXTERNPROTO */

	printf( "EXTERNPROTO Vector [\n" );
	printf( "\tfield  SFVec3f     translation\n" );
	printf( "\tfield  SFVec3f     scale\n" );
	printf( "\tfield  SFRotation  rotation\n" );
	printf( "\tfield  SFColor     color\n" );
	printf( "] \"vector2.wrl\"\n" );
	printf( "\n" );

	/* Generate a vector field using the Vector EXTERNPROTO */
	/* Compute the field using a set of crossed trig functions */

	for ( x = x0 ; x <= x1 ; x += xstep )
	{
		for ( y = y0 ; y <= y1 ; y += ystep )
		{
			for ( z = z0 ; z <= z1 ; z += zstep )
			{
				printf( "Vector {\n" );
					printf( "\ttranslation %f %f %f\n", x*s, y*s, z*s );

					/* Rotation is based on crossed trig functions */

					clen = fabs( sqrt( z*z + x*x ) );
					cross[0] = z / clen;
					cross[1] = 0;
					cross[2] = x / clen;
					theta = asin( cross[0] ) * acos( cross[2] );
					printf( "\trotation %f %f %f  %f\n",
						cross[0], cross[1], cross[2], theta );

					/* Color is based on crossed trig functions */

					color[0] = fabs(
						cos(x + phase[0]) *
						sin(y + phase[1]) *
						sin(z + phase[2])
					);
					color[1] = 0.0;
					color[2] = 1.0 - color[0];
					printf( "\tcolor %f %f %f\n",
						color[0], color[1], color[2] );

					/* Length is based on crossed trig functions */

					printf( "\tscale %f %f %f\n",
						1.0, 1.5*color[0]+0.1, 1.0 );

				printf( "}\n" );
				printf( "\n" );
			}
		}
	}

}


