[comp.graphics] 3d to 2d grid projection

greg@bluemtn.uucp (Greg Richter (2XS)) (07/02/90)

In response to various requests, attached is a simple grid projection
in Turbo C.


#include <graphics.h>
#include <alloc.h>
#include "colors.h"

#define XSTEP  82				/* Grid densities (82,180) */
#define YSTEP  160

#define VPX   XMIN+(XMAX-XMIN)/2 		/* Viewpoint	(82,165) */
#define VPY   90
#define VPZ   165

#define ORIGX (XMIN + (XMAX-XMIN)/2)	/* Three space origin for rotation*/
#define ORIGY 75
#define ORIGZ (ZMAX + (YMAX-ZMAX)/2)

/*** X3D and Y3D transform a 3 space point
 *** to its image on the XY plane.
 ***/


/***
		NAME
		x3d

		SYNOPSIS
		int x3d(px,py,pz,vx,vy,vz)
		float px, py, pz, vx, vy, vz;

		DESCRIPTION
		X3d computes the 2-dimensional x-value of a three dimensional
		point (px,py,pz) with viewpoint (vx,vy,vz).  The integer value
		of the x-value is returned.
***/

x3d(px,py,pz, vx,vy,vz)
float px,py,pz, vx,vy,vz;
{
 return( (int) (px - ( (vx-px) / (vz-pz) ) * pz) );
}


/***
		NAME
		y3d

		SYNOPSIS
		int y3d(px,py,pz,vx,vy,vz)
		float px, py, pz, vx, vy, vz;

		DESCRIPTION
		Y3d computes the 2-dimensional y-value of a three dimensional
		point (px,py,pz) with viewpoint (vx,vy,vz).  The integer value
		of the y-value is returned.
***/

y3d(px,py,pz, vx,vy,vz)
float px,py,pz, vx,vy,vz;
{
 return( (int) YMAX + (py + ( (vy-py) / (vz-pz) ) * pz) );
}


/***
		NAME
		draw_grid

		SYNOPSIS
		void draw_grid(pitch,roll,foreground)
		int pitch, roll, foreground;

		DESCRIPTION
	Draw_grid draws a 3 dimensional grid as a 2 dimensional projection
	inside a boxed area.  If foreground is 0, the previously drawn
	grid is erased, otherwise a new grid is drawn.  Pitch and Roll are
	given in degrees and they determine the pitch and roll of the grid.
***/

draw_grid(pitch,roll,foreground)
/*** Draw a three space grid as a two space projection inside a boxed area
 ***
 ***/
int pitch,roll,foreground;
{
float vpx=(float)VPX,vpy=(float)VPY,vpz=(float)VPZ;
int   i,j;
int   goplot;
int 	cx,cy,ex,ey,dx,dy,fx,fy;
float x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4;

  vpy -= pitch/4;
  setlinestyle(4,0x5555,1);

  if (vpy < 0) return(0);	/* no grid if not visible or underneath */

  for(i=XMIN;i<=XMAX+2;i+=XSTEP)
  {
	x1 = x2 = i;		/* grid corners to match flight box */
	z1 = z4 = ZMAX;
	x3 = x4 = i;
	z2 = z3 = ZMIN;
	y1 = y2 = y3 = y4 = 0;

	ex =  x3d(x1,y1,z1, vpx,vpy,vpz); ey = y3d(x1,y1,z1, vpx,vpy,vpz);
	cx =  x3d(x2,y2,z2, vpx,vpy,vpz); cy = y3d(x2,y2,z2, vpx,vpy,vpz);

	/* change to new coordinate system */
	ex -= ORIGX; ey -= ORIGY;
	cx -= ORIGX; cy -= ORIGY;

	/* rotate */
	rot(ex,ey,&ex,&ey,roll);
	rot(cx,cy,&cx,&cy,roll);

	/* restore coordinate system */
	ex += ORIGX; ey += ORIGY;
	cx += ORIGX; cy += ORIGY;

	if (foreground)
		if (i == XMIN || i == XMAX+2) setcolor(GRIDEDGE);
		else setcolor(GRID);
	else setcolor(ATTITUDE_BACKGROUND);

	goplot=clipper(&ex,&ey,&cx,&cy,XMIN,XMAX,YMIN,YMAX);
	if(goplot==0) line(ex,ey,cx,cy);
  }

  for(j=ZMAX;j<=ZMIN;j+=YSTEP)
  {
	x1 = x2 = XMIN;			/* grid corners to match flight box */
	z1 = z4 = j;
	x3 = x4 = XMAX;
	z2 = z3 = j;
	y1 = y2 = y3 = y4 = 0;

	cx =  x3d(x2,y2,z2, vpx,vpy,vpz); cy = y3d(x2,y2,z2, vpx,vpy,vpz);
	dx =	x3d(x3,y3,z3, vpx,vpy,vpz); dy = y3d(x3,y3,z3, vpx,vpy,vpz);

	/* change to new coordinate system */
	dx -= ORIGX; dy -= ORIGY;
	cx -= ORIGX; cy -= ORIGY;

	/* rotate */
	rot(dx,dy,&dx,&dy,roll);
	rot(cx,cy,&cx,&cy,roll);

	/* restore coordinate system */
	dx += ORIGX; dy += ORIGY;
	cx += ORIGX; cy += ORIGY;

	goplot=clipper(&cx,&cy,&dx,&dy,XMIN,XMAX,YMIN,YMAX);
	if(goplot == 0) line(cx,cy,dx,dy);          /* draw this line */

	if (i > YMIN && foreground) setcolor(GRID);
	else setcolor(ATTITUDE_BACKGROUND);
  }
 setlinestyle(0,0,1);
} /* drawgrid */


-- 
"Nothing to say, no place to say it."    | Greg Richter 
                                         | ..{uunet,emory}!bluemtn!greg 
-------------------------------------------------------------------------