[comp.graphics] 4D - 3D - 2D Transforms

la086318@zach.fit.edu ( Mark R. Craig) (08/21/90)

     Sorry to post this response to USENET but I'm not sure my mail got to
daffy@physics.vaxc.cc.monash.edu.au

NOTE to USENET readers:  If anyone has any input on this subject (ideas,
equations, code, etc.) please email me or post to USENET.

==========================================================================
     Here are some code segments from a 4d rotation program I wrote.
Projection type 6 is based on answers I got from USENET when I asked
about 4d projection methods.  Projection type 5 is one I derived before I
found out about projection type 6 - both give very similar results -
these are as close to stereographic projection (as described by
Dr. Thomas Banchoff) as I could find.
     I would be very greatful if you would forward any responses that you
get (or post to USENET).  Although I have gotten close to the elusive
stereographic (not to be confused with stereoscopic 3d displays)
projection, I'm still not getting the right results.  NOTE: projection
type 5 and 6 can give weird results.

Mark Craig
la086318@zach.fit.edu

float scale;
int verbose=0;
int nomove=0;
float rad;

inputs()
{
printf("Enter projection type: (1,2,3,4,5,6): ");
scanf("%d",&projection);
switch (projection)
	{
	case 2:
		printf("Enter coordinates of light source: x,y,z,w: ");
		scanf("%f %f %f %f",&lx,&ly,&lz,&lw);
		distance=sqrt(lx*lx+ly*ly+lz*lz+lw*lw);
		printf("Enter scale: ");
		scanf("%f",&scale);
		break;
	case 5:
		rad=1.0;
		break;
	case 6:
		rad=1.0; 
		scale=1.0; 
		distance=2.0*rad;
		break;
	}
}

... much code deleted ...

draw(xx,yy,zz,ww)
float xx,yy,zz,ww;
{
float xx1,yy1,zz1,z1,xx3,yy3,zz3;
float angxy,xn,scl;
switch (projection)
	{
	case 1:
		line_abs_2(xx,yy);
		if (verbose) printcoords(xx,yy,zz,ww,xx,yy);
		break;
	case 2:
		xx1=xx*distance/(distance-zz);
		yy1=yy*distance/(distance-zz);
		line_abs_2(xx1*scale,yy1*scale);
		if (verbose) printcoords(xx,yy,zz,ww,xx1*scale,yy1*scale);
		break;
	case 3:
		zz1=ww*.5/sqrt(2.0)+1.5;
		xx1=xx/zz1;
		yy1=yy/zz1;
		line_abs_2(xx1,yy1);
		if (verbose) printcoords(xx,yy,zz,ww,xx1,yy1);
		break;
	case 4:
		z1=ww*.5/sqrt(2.0)+1.5;
		zz1=(zz*.5/sqrt(2.0)+1.5)*z1;
		xx1=xx/zz1;
		yy1=yy/zz1;
		line_abs_2(xx1,yy1);
		if (verbose) printcoords(xx,yy,zz,ww,xx1,yy1);
		break;
	case 5:
		xn=(rad-zz)*4.0*rad/(2.0*rad-ww);
		angxy=arg(xx,yy);
		xx1=xn*cos(angxy);
		yy1=xn*sin(angxy);	
		line_abs_2(xx1,yy1);
		if (verbose) printcoords(xx,yy,zz,ww,xx1,yy1);
		break;
	case 6:
		scl=1.0-(ww/(2.0*rad-ww));
		xx3=xx*scl;
		yy3=yy*scl;
		zz3=zz*scl;
		if ((zz3!=distance) && (nomove==0))
			{
			xx1=xx3*distance/(distance-zz3);
			yy1=yy3*distance/(distance-zz3);
			line_abs_2(xx1*scale,yy1*scale);
			}
		nomove=0;
		if (verbose) printcoords(xx,yy,zz,ww,xx1*scale,yy1*scale);
		break;
	}
}
Mark R. Craig
Internet:  la086318@zach.fit.edu
UUCP:      ...!winnie!zach!la086318