summaryrefslogtreecommitdiff
path: root/Examples/GIFPlot/Lib/plot3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'Examples/GIFPlot/Lib/plot3d.c')
-rw-r--r--Examples/GIFPlot/Lib/plot3d.c2181
1 files changed, 0 insertions, 2181 deletions
diff --git a/Examples/GIFPlot/Lib/plot3d.c b/Examples/GIFPlot/Lib/plot3d.c
deleted file mode 100644
index 387e420e2..000000000
--- a/Examples/GIFPlot/Lib/plot3d.c
+++ /dev/null
@@ -1,2181 +0,0 @@
-/* -----------------------------------------------------------------------------
- * plot3d.c
- *
- * Three-dimensional plotting.
- *
- * Author(s) : David Beazley (beazley@cs.uchicago.edu)
- * Copyright (C) 1995-1996
- *
- * See the file LICENSE for information on usage and redistribution.
- * ----------------------------------------------------------------------------- */
-
-#define PLOT3D
-#include "gifplot.h"
-#include <math.h>
-#include <float.h>
-
-#define ORTHO 1
-#define PERSPECTIVE 2
-/* ------------------------------------------------------------------------
- Plot3D *new_Plot3D(FrameBuffer *f, double xmin, double ymin, double zmin,
- double xmax, double ymax, double zmax)
-
- Creates a new 3D plot. Min and max coordinates are primarily used to
- pick some default parameters. Returns NULL on failure
- ------------------------------------------------------------------------- */
-
-Plot3D *new_Plot3D(FrameBuffer *f, double xmin, double ymin, double zmin,
- double xmax, double ymax, double zmax) {
-
- Plot3D *p3;
- void Plot3D_maketransform(Plot3D *p3);
-
- /* Check to make sure the framebuffer and min/max parameters are valid */
-
- if (!f) return (Plot3D *) 0;
- if ((xmin > xmax) || (ymin > ymax) || (zmin > zmax)) return (Plot3D *) 0;
-
- p3 = (Plot3D *) malloc(sizeof(Plot3D));
- p3->frame = f;
- p3->xmin = xmin;
- p3->ymin = ymin;
- p3->zmin = zmin;
- p3->xmax = xmax;
- p3->ymax = ymax;
- p3->zmax = zmax;
-
- /* Set view region to the entire size of the framebuffer */
-
- p3->view_xmin = 0;
- p3->view_ymin = 0;
- p3->view_xmax = f->width;
- p3->view_ymax = f->height;
- p3->width = f->width;
- p3->height = f->height;
-
- /* Calculate a center point based off the min and max coordinates given */
-
- p3->xcenter = (xmax - xmin)/2.0 + xmin;
- p3->ycenter = (ymax - ymin)/2.0 + ymin;
- p3->zcenter = (zmax - zmin)/2.0 + zmin;
-
- /* Calculate the aspect ratio of the viewing region */
-
- p3->aspect = (double) f->width/(double) f->height;
-
- /* Set default view parameters */
- p3->xshift = 1.0;
- p3->yshift = 1.0;
- p3->zoom = 0.5;
- p3->fovy = 40.0; /* 40 degree field of view */
-
- /* Create matrices */
-
- p3->model_mat = new_Matrix();
- p3->view_mat = new_Matrix();
- p3->center_mat = new_Matrix();
- p3->fullmodel_mat = new_Matrix();
- p3->trans_mat = new_Matrix();
- p3->pers_mode = ORTHO;
-
- FrameBuffer_zresize(p3->frame,p3->width, p3->height);
- Matrix_identity(p3->view_mat);
- Matrix_identity(p3->model_mat);
- Matrix_translate(p3->center_mat, -p3->xcenter,-p3->ycenter,-p3->zcenter);
- Plot3D_maketransform(p3);
- return p3;
-}
-
-/* ---------------------------------------------------------------------
- delete_Plot3D(Plot3D *p3)
-
- Deletes a 3D plot
- --------------------------------------------------------------------- */
-
-void delete_Plot3D(Plot3D *p3) {
- if (p3) {
- delete_Matrix(p3->view_mat);
- delete_Matrix(p3->model_mat);
- delete_Matrix(p3->trans_mat);
- free((char *) p3);
- }
-}
-
-/* ---------------------------------------------------------------------
- Plot3D *Plot3D_copy(Plot3D *p3)
-
- This makes a copy of the 3D plot structure and returns a pointer to it.
- --------------------------------------------------------------------- */
-
-Plot3D *Plot3D_copy(Plot3D *p3) {
- Plot3D *c3;
- if (p3) {
- c3 = (Plot3D *) malloc(sizeof(Plot3D));
- if (c3) {
- c3->frame = p3->frame;
- c3->view_xmin = p3->view_xmin;
- c3->view_ymin = p3->view_ymin;
- c3->view_xmax = p3->view_xmax;
- c3->view_ymax = p3->view_ymax;
- c3->xmin = p3->xmin;
- c3->ymin = p3->ymin;
- c3->zmin = p3->zmin;
- c3->xmax = p3->xmax;
- c3->ymax = p3->ymax;
- c3->zmax = p3->zmax;
- c3->xcenter = p3->xcenter;
- c3->ycenter = p3->ycenter;
- c3->zcenter = p3->zcenter;
- c3->fovy = p3->fovy;
- c3->aspect = p3->aspect;
- c3->znear = p3->znear;
- c3->zfar = p3->zfar;
- c3->center_mat = Matrix_copy(p3->center_mat);
- c3->model_mat = Matrix_copy(p3->model_mat);
- c3->view_mat = Matrix_copy(p3->view_mat);
- c3->fullmodel_mat = Matrix_copy(p3->fullmodel_mat);
- c3->trans_mat = Matrix_copy(p3->trans_mat);
- c3->lookatz = p3->lookatz;
- c3->xshift = p3->xshift;
- c3->yshift = p3->yshift;
- c3->zoom = p3->zoom;
- c3->width = p3->width;
- c3->height = p3->height;
- c3->pers_mode = p3->pers_mode;
- }
- return c3;
- } else {
- return (Plot3D *) 0;
- }
-}
-
-/* ----------------------------------------------------------------------
- Plot3D_clear(Plot3D *p3, Pixel bgcolor)
-
- Clear the pixel and zbuffer only for the view region of this image.
- ---------------------------------------------------------------------- */
-void
-Plot3D_clear(Plot3D *p3, Pixel bgcolor) {
- int i,j;
-
- for (i = p3->view_xmin; i < p3->view_xmax; i++)
- for (j = p3->view_ymin; j < p3->view_ymax; j++) {
- p3->frame->pixels[j][i] = bgcolor;
- p3->frame->zbuffer[j][i] = ZMIN;
- }
-}
-
-/* ---------------------------------------------------------------------
- Plot3D_maketransform(Plot3D *p3)
-
- This function builds the total 3D transformation matrix from a
- collection of components.
-
- Trans = View * Rotation * Center
-
- Where View is the viewing transformation matrix, Rotation is the
- model rotation matrix, Center is the translation matrix used to
- center the Model at the origin.
- --------------------------------------------------------------------- */
-
-void
-Plot3D_maketransform(Plot3D *p3) {
-
- Matrix_multiply(p3->model_mat,p3->center_mat, p3->fullmodel_mat);
- Matrix_multiply(p3->view_mat,p3->fullmodel_mat, p3->trans_mat);
-}
-
-/* ---------------------------------------------------------------------
- Plot3D_perspective(Plot3D *p3, double fovy, double znear, double zfar)
-
- Sets up the perspective viewing transformation. Assumes "lookat"
- has already been called.
- --------------------------------------------------------------------- */
-
-void
-Plot3D_perspective(Plot3D *p3, double fovy, double znear, double zfar) {
- double theta;
- double mat[16];
-
- p3->fovy = fovy;
- p3->znear = znear;
- p3->zfar = zfar;
-
- theta = 3.1415926*fovy/180.0;
-
- Matrix_identity(mat);
- mat[0] = cos(theta/2.0)/(sin(theta/2.0)*p3->aspect);
- mat[5] = cos(theta/2.0)/(sin(theta/2.0));
- mat[10] = -(zfar + znear)/(zfar-znear);
- mat[14] = -1.0;
- mat[11] = -(2*zfar*znear)/(zfar - znear);
- mat[15] = 0.0;
-
- /* Update the view transformation matrix */
-
- Matrix_multiply(mat,p3->view_mat,p3->view_mat);
-
- /* Update the global transformation matrix */
-
- Plot3D_maketransform(p3);
- p3->pers_mode = PERSPECTIVE;
-
-}
-
-/* ---------------------------------------------------------------------
- Plot3D_lookat(Plot3D *p3, double z)
-
- A greatly simplified version of (lookat). Specifies the position
- of the viewpoint. (can be used for moving image in or out).
-
- Destroys the current viewing transformation matrix, so it will have
- to be recalculated.
- --------------------------------------------------------------------- */
-
-void
-Plot3D_lookat(Plot3D *p3, double z) {
- if (p3) {
- Matrix_translate(p3->view_mat, 0,0,-z);
- p3->lookatz = z;
- Plot3D_maketransform(p3);
- }
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_autoperspective(Plot3D *p3, double fovy)
-
- Automatically figures out a semi-decent viewpoint given the
- min,max parameters currently set for this image
- ------------------------------------------------------------------------- */
-
-void
-Plot3D_autoperspective(Plot3D *p3, double fovy) {
-
- /* Make a perspective transformation matrix for this system */
-
- double zfar;
- double znear;
- double d, dmax;
- double cx,cy,cz;
- double xmin,xmax,ymin,ymax,zmin,zmax;
-
- xmin = p3->xmin;
- ymin = p3->ymin;
- zmin = p3->zmin;
- xmax = p3->xmax;
- ymax = p3->ymax;
- zmax = p3->zmax;
- cx = p3->xcenter;
- cy = p3->ycenter;
- cz = p3->zcenter;
-
- /* Calculate longest point from center point */
-
- dmax = (xmin-cx)*(xmin-cx) + (ymin-cy)*(ymin-cy) + (zmin-cz)*(zmin-cz);
- d = (xmax-cx)*(xmax-cx) + (ymin-cy)*(ymin-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymax-cy)*(ymax-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymax-cy)*(ymax-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymin-cy)*(ymin-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymin-cy)*(ymin-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymax-cy)*(ymax-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymax-cy)*(ymax-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
-
- dmax = sqrt(dmax);
- d = p3->lookatz;
-
- znear = d - dmax;
- zfar = znear+1.5*dmax;
- Plot3D_perspective(p3, fovy,znear,zfar);
-
-}
-
-
-/* ---------------------------------------------------------------------
- Plot3D_ortho(Plot3D *p3, double left, double right, double bottom, double top)
-
- Sets up an orthographic viewing transformation.
- --------------------------------------------------------------------- */
-
-void
-Plot3D_ortho(Plot3D *p3, double left, double right, double bottom, double top) {
-
-
- Matrix_identity(p3->view_mat);
- p3->view_mat[0] = (2.0/(right - left))/p3->aspect;
- p3->view_mat[5] = 2.0/(top - bottom);
- p3->view_mat[10] = -1;
- p3->view_mat[15] = 1.0;
- p3->view_mat[3] = -(right+left)/(right-left);
- p3->view_mat[7] = -(top+bottom)/(top-bottom);
-
- /* Update the global transformation matrix */
-
- Plot3D_maketransform(p3);
- p3->pers_mode = ORTHO;
- p3->ortho_left = left;
- p3->ortho_right = right;
- p3->ortho_bottom = bottom;
- p3->ortho_top = top;
-
-}
-
-/* ---------------------------------------------------------------------
- Plot3D_autoortho(Plot3D *p3)
-
- Automatically pick an orthographic projection that's probably
- pretty good.
- --------------------------------------------------------------------- */
-
-void
-Plot3D_autoortho(Plot3D *p3) {
-
- /* Make a perspective transformation matrix for this system */
-
- double d, dmax;
- double cx,cy,cz;
- double xmin,xmax,ymin,ymax,zmin,zmax;
-
- xmin = p3->xmin;
- ymin = p3->ymin;
- zmin = p3->zmin;
- xmax = p3->xmax;
- ymax = p3->ymax;
- zmax = p3->zmax;
- cx = p3->xcenter;
- cy = p3->ycenter;
- cz = p3->zcenter;
-
- /* Calculate longest point from center point */
-
- dmax = (xmin-cx)*(xmin-cx) + (ymin-cy)*(ymin-cy) + (zmin-cz)*(zmin-cz);
- d = (xmax-cx)*(xmax-cx) + (ymin-cy)*(ymin-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymax-cy)*(ymax-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymax-cy)*(ymax-cy) + (zmin-cz)*(zmin-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymin-cy)*(ymin-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymin-cy)*(ymin-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmin-cx)*(xmin-cx) + (ymax-cy)*(ymax-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
- d = (xmax-cx)*(xmax-cx) + (ymax-cy)*(ymax-cy) + (zmax-cz)*(zmax-cz);
- if (d > dmax) dmax = d;
-
- dmax = sqrt(dmax);
-
- Plot3D_ortho(p3,-dmax,dmax,-dmax,dmax);
-
-}
-
-
-
-/* -------------------------------------------------------------------------
- Plot3D_setview(Plot3D *p3, int vxmin, int vymin, int vxmax, int vymax)
-
- Sets the viewport for this 3D graph. Will recalculate all of the
- local viewing transformation matrices accordingly.
- ------------------------------------------------------------------------- */
-void
-Plot3D_setview(Plot3D *p3, int vxmin, int vymin, int vxmax, int vymax) {
- if (p3) {
- if ((vxmin > vxmax) || (vymin >vymax)) return;
- p3->view_xmin = vxmin;
- p3->view_ymin = vymin;
- p3->view_xmax = vxmax;
- p3->view_ymax = vymax;
- p3->width = (vxmax - vxmin);
- p3->height = (vymax - vymin);
- p3->aspect = (double) p3->width/(double) p3->height;
-
- /* Fix up the viewing transformation matrix */
-
- if (p3->pers_mode == PERSPECTIVE) {
- Plot3D_lookat(p3,p3->lookatz);
- Plot3D_perspective(p3,p3->fovy,p3->znear,p3->zfar);
- } else {
- Plot3D_ortho(p3,p3->ortho_left,p3->ortho_right,p3->ortho_bottom, p3->ortho_top);
- }
- FrameBuffer_setclip(p3->frame,vxmin,vymin,vxmax,vymax);
- }
-}
-
-/* ---------------------------------------------------------------------------
- Plot2D_start(Plot2D *p3)
-
- Set up viewing region and other parameters for this image.
- --------------------------------------------------------------------------- */
-
-void
-Plot3D_start(Plot3D *p3) {
- if (p3)
- FrameBuffer_setclip(p3->frame, p3->view_xmin,p3->view_ymin,p3->view_xmax, p3->view_ymax);
-
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_plot(Plot3D *p3, double x, double y, double z, Pixel Color)
-
- Plot a 3D point
- ------------------------------------------------------------------------- */
-
-void
-Plot3D_plot(Plot3D *p3, double x, double y, double z, Pixel color) {
-
- GL_Vector t;
- int ix, iy;
- double invw;
- FrameBuffer *f;
-
- /* Perform a transformation */
-
- Matrix_transform4(p3->trans_mat,x,y,z,1,&t);
-
- /* Scale the coordinates into unit cube */
-
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
-#ifdef GL_DEBUG
- fprintf(stdout,"t.x = %g, t.y = %g, t.z = %g\n", t.x,t.y,t.z);
-#endif
- /* Calculate the x and y coordinates */
-
- ix = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5);
- iy = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5);
-
- if ((ix >= 0) && (ix < p3->width) &&
- (iy >= 0) && (ix < p3->height)) {
- ix += p3->view_xmin;
- iy += p3->view_ymin;
- f = p3->frame;
- if (t.z <= f->zbuffer[iy][ix]) {
- f->pixels[iy][ix] = color;
- f->zbuffer[iy][ix] = t.z;
- }
- }
-}
-
-/* ----------------------------------------------------------------------
- Plot3D_rotx(Plot3D *p3, double deg)
-
- Rotate the model around its x axis.
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotx(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatex(temp,deg); /* Construct a x rotation matrix */
- Matrix_multiply(p3->model_mat,temp,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-/* ----------------------------------------------------------------------
- Plot3D_roty(Plot3D *p3, double deg)
-
- Rotate the model around its y axis.
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_roty(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatey(temp,deg); /* Construct a y rotation matrix */
- Matrix_multiply(p3->model_mat,temp,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-/* ----------------------------------------------------------------------
- Plot3D_rotz(Plot3D *p3, double deg)
-
- Rotate the model around its z axis.
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotz(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatez(temp,deg); /* Construct a z rotation matrix */
- Matrix_multiply(p3->model_mat,temp,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-
-/* ----------------------------------------------------------------------
- Plot3D_rotd(Plot3D *p3, double deg)
-
- Rotate the model down
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotd(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatex(temp,deg); /* Construct a x rotation matrix */
- Matrix_multiply(temp, p3->model_mat,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-
-/* ----------------------------------------------------------------------
- Plot3D_rotu(Plot3D *p3, double deg)
-
- Rotate the model up
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotu(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatex(temp,-deg); /* Construct a x rotation matrix */
- Matrix_multiply(temp,p3->model_mat,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-
-/* ----------------------------------------------------------------------
- Plot3D_rotr(Plot3D *p3, double deg)
-
- Rotate the model down
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotr(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatey(temp,deg); /* Construct a y rotation matrix */
- Matrix_multiply(temp, p3->model_mat,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-
-/* ----------------------------------------------------------------------
- Plot3D_rotl(Plot3D *p3, double deg)
-
- Rotate the model left
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotl(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatey(temp,-deg); /* Construct a y rotation matrix */
- Matrix_multiply(temp,p3->model_mat,p3->model_mat);
- Plot3D_maketransform(p3);
-
-}
-
-
-/* ----------------------------------------------------------------------
- Plot3D_rotc(Plot3D *p3, double deg)
-
- Rotate the model around center point
- ---------------------------------------------------------------------- */
-
-void
-Plot3D_rotc(Plot3D *p3, double deg) {
- double temp[16];
-
- Matrix_rotatez(temp,-deg); /* Construct a z rotation matrix */
- Matrix_multiply(temp,p3->model_mat,p3->model_mat);
- Plot3D_maketransform(p3);
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_zoom(Plot3D *p3, double percent)
-
- Zooms in or out the current image. percent defines a percentage of
- zoom.
-
- Zooming is actually done by adjusting the perspective field of view
- instead of scaling the model or moving in the viewpoint. This
- seems to work the best.
- ------------------------------------------------------------------------- */
-
-void
-Plot3D_zoom(Plot3D *p3, double percent) {
-
- double scale;
- double dx;
- if (percent <= 0) return;
- scale = percent/100.0;
-
- dx = (1.0/scale - 1.0)/(2*p3->zoom); /* Don't even ask where this came from */
- p3->xshift += dx;
- p3->yshift += dx;
- p3->zoom = p3->zoom*scale;
-
-#ifdef OLD
- p3->fovy = p3->fovy*scale;
- if (p3->fovy > 170.0) p3->fovy = 170.0;
- if (p3->fovy == 0) p3->fovy = 0.0001;
- Plot3D_lookat(p3,p3->lookatz);
- Plot3D_perspective(p3,p3->fovy,p3->znear,p3->zfar);
-#endif
-}
-
-/* --------------------------------------------------------------------------
- Plot3D_left(Plot3D *p3, double s)
-
- Shifts the image to the left by s units. This is a little funky.
-
- s is scaled so that s = 100 equals one full screen.
- -------------------------------------------------------------------------- */
-void
-Plot3D_left(Plot3D *p3, double s) {
- p3->xshift -= (s/100.0)/p3->zoom;
-}
-
-/* --------------------------------------------------------------------------
- Plot3D_right(Plot3D *p3, double s)
-
- Shifts the image to the right by s units.
-
- s is scaled so that s = 100 equals one full screen.
- -------------------------------------------------------------------------- */
-void
-Plot3D_right(Plot3D *p3, double s) {
- p3->xshift += (s/100.0)/p3->zoom;
-}
-
-/* --------------------------------------------------------------------------
- Plot3D_up(Plot3D *p3, double s)
-
- Shifts the image up left by s units.
-
- s is scaled so that s = 100 equals one full screen.
- -------------------------------------------------------------------------- */
-void
-Plot3D_up(Plot3D *p3, double s) {
- p3->yshift += (s/100.0)/p3->zoom;
-}
-
-/* --------------------------------------------------------------------------
- Plot3D_down(Plot3D *p3, double s)
-
- Shifts the image down by s units.
-
- s is scaled so that s = 100 equals one full screen.
- -------------------------------------------------------------------------- */
-void
-Plot3D_down(Plot3D *p3, double s) {
- p3->yshift -= (s/100.0)/p3->zoom;
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_center(Plot3D *p3, double cx, double cy)
-
- Centers the image on a point in the range (0,0) - (100,100)
- ------------------------------------------------------------------------- */
-void
-Plot3D_center(Plot3D *p3, double cx, double cy) {
- Plot3D_left(p3,cx-50);
- Plot3D_down(p3,cy-50);
-}
-
-
-
-/***************************************************************************
- * 3d Primitives *
- ***************************************************************************/
-
-/* -------------------------------------------------------------------------
- Plot3D_horizontal(Plot3D *p3, int xmin, int xmax, int y, double z1, double z2, Pixel color)
-
- Draws a "Horizontal" line on the framebuffer between two screen coordinates,
- but also supplies z-values and zbuffering. This function probably isn't
- too useful by itself, but will be used by a number of other primitives.
- -------------------------------------------------------------------------- */
-
-void Plot3D_horizontal(Plot3D *p3, int xmin, int xmax, int y, Zvalue z1, Zvalue z2, Pixel color) {
- Pixel *p;
- FrameBuffer *f;
- int i;
- Zvalue *zbuf,z,mz;
- int startx, endx;
-
- f = p3->frame;
- if ((y < f->ymin) || (y >= f->ymax)) return;
- if (xmin > f->xmax) return;
- if (xmin < f->xmin) startx = f->xmin;
- else startx = xmin;
- if (xmax < f->xmin) return;
- if (xmax >= f->xmax) endx = f->xmax - 1;
- else endx = xmax;
-
- /* Calculate z slope */
-
- if (xmax != xmin) {
- mz = (Zvalue) ((double) (z2 - z1)/(double) (xmax - xmin));
- } else {
- mz = 0;
- }
-
- /* Draw it */
-
- p = &f->pixels[y][startx];
- zbuf = &f->zbuffer[y][startx];
- z = (Zvalue) (mz*(startx-xmin) + z1);
- for (i = startx; i <= endx; i++, p++, zbuf++,z+=mz) {
- if (z <= *zbuf) {
- *p = color;
- *zbuf = z;
- }
- }
-}
-
-
-/* -------------------------------------------------------------------------
- Plot3D_vertical(Plot3D *p3, int ymin, int ymax, int x, double z1, double z2, Pixel color)
-
- Draws a "Vertical" line on the framebuffer between two screen coordinates,
- but also supplies z-values and zbuffering. This function probably isn't
- too useful by itself, but will be used by a number of other primitives.
- -------------------------------------------------------------------------- */
-
-void Plot3D_vertical(Plot3D *p3, int ymin, int ymax, int x, Zvalue z1, Zvalue z2, Pixel color) {
- Pixel *p;
- FrameBuffer *f;
- int i;
- Zvalue *zbuf,z,mz;
- int starty, endy;
-
- f = p3->frame;
- if ((x < f->xmin) || (x >= f->xmax)) return;
- if (ymin >= f->ymax) return;
- if (ymin < f->ymin) starty = f->ymin;
- else starty = ymin;
- if (ymax < f->ymin) return;
- if (ymax >= f->ymax) endy = f->ymax - 1;
- else endy = ymax;
-
- /* Calculate z slope */
-
- mz = (double) (z2 - z1)/(double) (ymax - ymin);
-
- /* Draw it */
-
- p = &f->pixels[starty][x];
- zbuf = &f->zbuffer[starty][x];
- for (i = starty; i <= endy; i++, p+=f->width, zbuf+=f->width) {
- z = (Zvalue) (mz*(i-ymin) + z1);
- if (z <= *zbuf) {
- *p = color;
- *zbuf = z;
- }
- }
-}
-
-/* -------------------------------------------------------------------------------
- Plot3D_linetransform(Plot3D *p3, int x1, int y1, Zvalue z1,
- int x2, int y2, Zvalue z2, Pixel c)
-
- Draw a 3D line between points that have already been transformed into
- 3D space.
-
- Uses a Bresenham line algorithm, but with linear interpolation between
- Zvalues.
- ------------------------------------------------------------------------------- */
-
-void
-Plot3D_linetransform(Plot3D *p3, int x1, int y1, Zvalue z1, int x2, int y2, Zvalue z2, Pixel c) {
-
- int orig_x1, orig_y1, orig_x2,orig_y2;
- Zvalue zt;
-
- /* Bresenham line drawing parameters */
- FrameBuffer *f;
- int dx,dy,dxneg,dyneg, inc1,inc2,di;
- int x, y, xpixels, ypixels, xt, yt;
- Pixel *p;
- double m;
- int end1 = 0, end2 = 0;
- Zvalue *zbuf,mz,z;
-
- f = p3->frame;
-
- /* Need to figure out where in the heck this line is */
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- if ((dx == 0) && (dy == 0)) {
- if ((x1 < f->xmin) || (x1 >= f->xmax) ||
- (y1 < f->ymin) || (y1 >= f->ymax)) return;
- if (z1 <= f->zbuffer[y1][x1]) {
- f->pixels[y1][x1] = c;
- }
- return;
- }
- if (dx == 0) {
- /* Draw a Vertical Line */
- if (y1 < y2)
- Plot3D_vertical(p3,y1,y2,x1,z1,z2,c);
- else
- Plot3D_vertical(p3,y2,y1,x1,z2,z1,c);
- return;
- }
- if (dy == 0) {
- /* Draw a Horizontal Line */
- if (x1 < x2)
- Plot3D_horizontal(p3,x1,x2,y1,z1,z2,c);
- else
- Plot3D_horizontal(p3,x2,x1,y1,z2,z1,c);
- return;
- }
-
- /* Figure out where in the heck these lines are using the
- Cohen-Sutherland Line Clipping Scheme. */
-
- end1 = ((x1 - f->xmin) < 0) |
- (((f->xmax- 1 - x1) < 0) << 1) |
- (((y1 - f->ymin) < 0) << 2) |
- (((f->ymax-1 - y1) < 0) << 3);
-
- end2 = ((x2 - f->xmin) < 0) |
- (((f->xmax-1 - x2) < 0) << 1) |
- (((y2 - f->ymin) < 0) << 2) |
- (((f->ymax-1 - y2) < 0) << 3);
-
- if (end1 & end2) return; /* Nope : Not visible */
-
- /* Make sure points have a favorable orientation */
-
- if (x1 > x2) {
- xt = x1;
- x1 = x2;
- x2 = xt;
- yt = y1;
- y1 = y2;
- y2 = yt;
- zt = z1;
- z1 = z2;
- z2 = zt;
- }
-
- /* Save original points before we clip them off */
- orig_x1 = x1;
- orig_y1 = y1;
- orig_x2 = x2;
- orig_y2 = y2;
-
- /* Clip against the boundaries */
- m = (y2 - y1)/(double) (x2-x1);
- if (x1 < f->xmin) {
- y1 = (f->xmin - x1)*m + y1;
- x1 = f->xmin;
- }
- if (x2 >= f->xmax) {
- y2 = (f->xmax -1 -x1)*m + y1;
- x2 = f->xmax - 1;
- }
-
- if (y1 > y2) {
- xt = x1;
- x1 = x2;
- x2 = xt;
- yt = y1;
- y1 = y2;
- y2 = yt;
- zt = z1;
- z1 = z2;
- z2 = zt;
-
- /* Swap original points */
-
- xt = orig_x1;
- orig_x1 = orig_x2;
- orig_x2 = xt;
- yt = orig_y1;
- orig_y1 = orig_y2;
- orig_y2 = yt;
- }
-
- m = 1/m;
- if (y1 < f->ymin) {
- x1 = (f->ymin - y1)*m + x1;
- y1 = f->ymin;
- }
- if (y2 >= f->ymax) {
- x2 = (f->ymax-1-y1)*m + x1;
- y2 = f->ymax-1;
- }
-
- if ((x1 < f->xmin) || (x1 >= f->xmax) || (y1 < f->ymin) || (y1 >= f->ymax) ||
- (x2 < f->xmin) || (x2 >= f->xmax) || (y2 < f->ymin) || (y2 >= f->ymax)) return;
-
- dx = x2 - x1;
- dy = y2 - y1;
- xpixels = f->width;
- ypixels = f->height;
-
- dxneg = (dx < 0) ? 1 : 0;
- dyneg = (dy < 0) ? 1 : 0;
-
- dx = abs(dx);
- dy = abs(dy);
- if (dx >= dy) {
- /* Slope between -1 and 1. */
- mz = (z2 - z1)/(orig_x2 - orig_x1); /* Z interpolation slope */
- if (dxneg) {
- x = x1;
- y = y1;
- x1 = x2;
- y1 = y2;
- x2 = x;
- y2 = y;
- dyneg = !dyneg;
- }
- inc1 = 2*dy;
- inc2 = 2*(dy-dx);
- di = 2*dy-dx;
-
- /* Draw a line using x as independent variable */
-
- p = &f->pixels[y1][x1];
- zbuf = &f->zbuffer[y1][x1];
- x = x1;
- while (x <= x2) {
- /* Do a z-buffer check */
- z = mz*(x-orig_x1)+z1;
- if (z <= *zbuf){
- *p = c;
- *zbuf = z;
- }
- p++;
- zbuf++;
- if (di < 0) {
- di = di + inc1;
- } else {
- if (dyneg) {
- p = p - xpixels;
- zbuf = zbuf - xpixels;
- di = di + inc2;
- } else {
- p = p + xpixels;
- zbuf = zbuf + xpixels;
- di = di + inc2;
- }
- }
- x++;
- }
- } else {
- /* Slope < -1 or > 1 */
- mz = (z2 - z1)/(double) (orig_y2 - orig_y1);
- if (dyneg) {
- x = x1;
- y = y1;
- x1 = x2;
- y1 = y2;
- x2 = x;
- y2 = y;
- dxneg = !dxneg;
- }
- inc1 = 2*dx;
- inc2 = 2*(dx-dy);
- di = 2*dx-dy;
-
- /* Draw a line using y as independent variable */
-
- p = &f->pixels[y1][x1];
- zbuf = &f->zbuffer[y1][x1];
- y = y1;
- while (y <= y2) {
- /* Do a z-buffer check */
- z = mz*(y-orig_y1)+z1;
- if (z <= *zbuf) {
- *p = c;
- *zbuf = z;
- }
- p = p + xpixels;
- zbuf = zbuf + xpixels;
- if (di < 0) {
- di = di + inc1;
- } else {
- if (dxneg) {
- p = p - 1;
- zbuf = zbuf - 1;
- di = di + inc2;
- } else {
- p = p + 1;
- zbuf = zbuf + 1;
- di = di + inc2;
- }
- }
- y++;
- }
- }
-}
-
-/* ---------------------------------------------------------------------------
- Plot3D_line(Plot3D *p3, double x1, double y1, double z1, double x2, double y2, double z2,int color)
-
- Draws a line in 3D space. This is done as follows (for lack of a better
- method).
-
- 1. The points (x1,y1,z1) and (x2,y2,z2) are transformed into screen coordinates
- 2. We draw the line using a modified Bresenham line algorithm.
- 3. Zbuffer values are linearly interpolated between the two points.
- ---------------------------------------------------------------------------- */
-
-void
-Plot3D_line(Plot3D *p3, double fx1, double fy1, double fz1, double fx2, double fy2,
- double fz2, Pixel c) {
-
- /* 3D Transformation parameters */
- GL_Vector t;
- double invw;
- int x1,y1,x2,y2;
- Zvalue z1,z2;
-
- /* Transform the two points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,fx1,fy1,fz1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- x1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- y1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- z1 = t.z;
-
- Matrix_transform4(p3->trans_mat,fx2,fy2,fz2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- x2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- y2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- z2 = t.z;
- Plot3D_linetransform(p3,x1,y1,z1,x2,y2,z2,c);
-}
-
-
-/* -------------------------------------------------------------------------
- Plot3D_triangle(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- Pixel fillcolor)
-
- This function draws a 3D z-buffered outline triangle.
- -------------------------------------------------------------------------- */
-
-void Plot3D_triangle(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3, Pixel color) {
-
- int tx1, tx2, tx3, ty1, ty2, ty3;
- Zvalue tz1, tz2, tz3;
- GL_Vector t;
- double invw;
-
- /* Transform the three points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,x1,y1,z1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz1 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x2,y2,z2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz2 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x3,y3,z3,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx3 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty3 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz3 = (Zvalue) t.z;
-
-
- Plot3D_linetransform(p3,tx1,ty1,tz1,tx2,ty2,tz2,color);
- Plot3D_linetransform(p3,tx1,ty1,tz1,tx3,ty3,tz3,color);
- Plot3D_linetransform(p3,tx2,ty2,tz2,tx3,ty3,tz3,color);
-}
-
-
-/* -------------------------------------------------------------------------
- Plot3D_solidtriangletransform(Plot3D *p3, int tx1, int ty2, Zvalue tz1,
- int tx2, int ty2, Zvalue tz2,
- int tx3, int ty3, Zvalue tz3, Pixel color)
-
- This function draws a 3D z-buffered filled triangle. Assumes three
- points have already been transformed into screen coordinates.
-
- General idea :
- 1. Transform the three points into screen coordinates
- 2. Order three points vertically on screen.
- 3. Check for degenerate cases (where 3 points are colinear).
- 4. Fill in the resulting triangle using horizontal lines.
- -------------------------------------------------------------------------- */
-
-void Plot3D_solidtriangletransform(Plot3D *p3, int tx1, int ty1, Zvalue tz1,
- int tx2, int ty2, Zvalue tz2,
- int tx3, int ty3, Zvalue tz3, Pixel color) {
- int tempx, tempy;
- Zvalue tempz;
- double m1,m2,m3, mz1, mz2, mz3;
- int y;
- int ix1, ix2;
- Zvalue zz1, zz2;
- FrameBuffer *f;
- register double fy1,fy2;
- register Zvalue fz1,fz2;
-
- f = p3->frame;
-
- /* Check for degenerate cases here */
-
- if ((ty1 == ty2) && (ty2 == ty3)) {
- if (tx2 < tx1) { /* Swap points 1 and 2 if 2 is higher */
- tempx = tx1;
- tempz = tz1;
- tx1 = tx2;
- tz1 = tz2;
- tx2 = tempx;
- tz2 = tempz;
- }
- if (tx3 < tx1) { /* Swap points 1 and 3 if 3 is higher */
- tempx = tx1;
- tempz = tz1;
- tx1 = tx3;
- tz1 = tz3;
- tx3 = tempx;
- tz3 = tempz;
- }
- if (tx3 < tx2) { /* Swap points 2 and 3 if 3 is higher */
- tempx = tx2;
- tempz = tz2;
- tx2 = tx3;
- tz2 = tz3;
- tx3 = tempx;
- tz3 = tempz;
- }
-
- /* Points are aligned horizontally. Handle as a special case */
- /* Just draw three lines using the outline color */
-
- Plot3D_horizontal(p3,tx1,tx2,ty1,tz1,tz3,color);
-
- /* Plot3D_linetransform(p3,tx1,ty1,tz1,tx2,ty2,tz2,color);
- Plot3D_linetransform(p3,tx1,ty1,tz1,tx3,ty3,tz3,color);
- Plot3D_linetransform(p3,tx2,ty2,tz2,tx3,ty3,tz3,color);
- */
-
- return;
- }
-
- /* Figure out which point has the greatest "y" value */
-
- if (ty2 > ty1) { /* Swap points 1 and 2 if 2 is higher */
- tempx = tx1;
- tempy = ty1;
- tempz = tz1;
- tx1 = tx2;
- ty1 = ty2;
- tz1 = tz2;
- tx2 = tempx;
- ty2 = tempy;
- tz2 = tempz;
- }
- if (ty3 > ty1) { /* Swap points 1 and 3 if 3 is higher */
- tempx = tx1;
- tempy = ty1;
- tempz = tz1;
- tx1 = tx3;
- ty1 = ty3;
- tz1 = tz3;
- tx3 = tempx;
- ty3 = tempy;
- tz3 = tempz;
- }
- if (ty3 > ty2) { /* Swap points 2 and 3 if 3 is higher */
- tempx = tx2;
- tempy = ty2;
- tempz = tz2;
- tx2 = tx3;
- ty2 = ty3;
- tz2 = tz3;
- tx3 = tempx;
- ty3 = tempy;
- tz3 = tempz;
- }
-
- /* Points are now order so that t_1 is the highest point, t_2 is the
- middle point, and t_3 is the lowest point */
-
- if (ty2 < ty1) {
- /* First process line segments between (x1,y1)-(x2,y2)
- And between (x1,y1),(x3,y3) */
-
- m1 = (double) (tx2 - tx1)/(double) (ty2 - ty1);
- m2 = (double) (tx3 - tx1)/(double) (ty3 - ty1);
- mz1 = (tz2 - tz1)/(double) (ty2 - ty1);
- mz2 = (tz3 - tz1)/(double) (ty3 - ty1);
-
- y = ty1;
- fy1 = m1*(y-ty1)+0.5 + tx1;
- fy2 = m2*(y-ty1)+0.5 + tx1;
- fz1 = mz1*(y-ty1) + tz1;
- fz2 = mz2*(y-ty1) + tz1;
- while (y >= ty2) {
- /* Replace with bresenham scheme */
- /* Calculate x values from slope */
- ix1 = (int) fy1;
- ix2 = (int) fy2;
- zz1 = fz1;
- zz2 = fz2;
- fy1-= m1;
- fy2-= m2;
- fz1-= mz1;
- fz2-= mz2;
- if (ix1 > ix2)
- Plot3D_horizontal(p3,ix2,ix1,y,zz2,zz1,color);
- else
- Plot3D_horizontal(p3,ix1,ix2,y,zz1,zz2,color);
- y--;
- }
- }
- if (ty3 < ty2) {
- /* Draw lower half of the triangle */
- m2 = (double) (tx3 - tx1)/(double) (ty3 - ty1);
- m3 = (double) (tx3 - tx2)/(double)(ty3 - ty2);
- mz2 = (tz3 - tz1)/(double) (ty3 - ty1);
- mz3 = (tz3 - tz2)/(double) (ty3 - ty2);
- y = ty2;
- while (y >= ty3) {
- ix1 = (int) (m3*(y-ty2)+0.5)+tx2;
- ix2 = (int) (m2*(y-ty1)+0.5)+tx1;
- zz1 = mz3*(y-ty2)+tz2;
- zz2 = mz2*(y-ty1)+tz1;
- if (ix1 > ix2)
- Plot3D_horizontal(p3,ix2,ix1,y,zz2,zz1,color);
- else
- Plot3D_horizontal(p3,ix1,ix2,y,zz1,zz2,color);
- y--;
- }
- }
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_solidtriangle(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- Pixel color)
-
- This function draws a 3D z-buffered filled triangle. Can be used to
- draw other primitives such as quadralaterals, etc...
-
- This function simply transforms the given points and calls
- Plot3D_SolidTriangleTransform().
- -------------------------------------------------------------------------- */
-
-void Plot3D_solidtriangle(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3, Pixel color) {
-
- int tx1, tx2, tx3, ty1, ty2, ty3;
- Zvalue tz1, tz2, tz3;
- GL_Vector t;
- double invw;
- Matrix a;
- register double xshift, yshift, zoom, width, height, view_xmin, view_ymin;
-
- a = p3->trans_mat;
- xshift = p3->xshift;
- yshift = p3->yshift;
- zoom = p3->zoom;
- height = p3->height;
- width = p3->width;
- view_xmin = p3->view_xmin;
- view_ymin = p3->view_ymin;
-
- /* Transform the three points into screen coordinates */
-
- t.w = a[12]*x1 + a[13]*y1 + a[14]*z1 + a[15];
- invw = 1.0/t.w;
- t.x = (a[0]*x1 + a[1]*y1 + a[2]*z1 + a[3])*invw;
- t.y = (a[4]*x1 + a[5]*y1 + a[6]*z1 + a[7])*invw;
- t.z = (a[8]*x1 + a[9]*y1 + a[10]*z1 + a[11])*invw;
-
- tx1 = (int) ((t.x +xshift)*zoom*width + 0.5) + view_xmin;
- ty1 = (int) ((t.y +yshift)*zoom*height + 0.5) + view_ymin;
- tz1 = (Zvalue) t.z;
-
-
- t.w = a[12]*x2 + a[13]*y2 + a[14]*z2 + a[15];
- invw = 1.0/t.w;
- t.x = (a[0]*x2 + a[1]*y2 + a[2]*z2 + a[3])*invw;
- t.y = (a[4]*x2 + a[5]*y2 + a[6]*z2 + a[7])*invw;
- t.z = (a[8]*x2 + a[9]*y2 + a[10]*z2 + a[11])*invw;
- tx2 = (int) ((t.x +xshift)*zoom*width + 0.5) + view_xmin;
- ty2 = (int) ((t.y +yshift)*zoom*height + 0.5) + view_ymin;
- tz2 = (Zvalue) t.z;
-
- t.w = a[12]*x3 + a[13]*y3 + a[14]*z3 + a[15];
- invw = 1.0/t.w;
- t.x = (a[0]*x3 + a[1]*y3 + a[2]*z3 + a[3])*invw;
- t.y = (a[4]*x3 + a[5]*y3 + a[6]*z3 + a[7])*invw;
- t.z = (a[8]*x3 + a[9]*y3 + a[10]*z3 + a[11])*invw;
- tx3 = (int) ((t.x +xshift)*zoom*width + 0.5) + view_xmin;
- ty3 = (int) ((t.y +yshift)*zoom*height + 0.5) + view_ymin;
- tz3 = (Zvalue) t.z;
-
- Plot3D_solidtriangletransform(p3,tx1,ty1,tz1,tx2,ty2,tz2,tx3,ty3,tz3,color);
-
-}
-
-
-/* -------------------------------------------------------------------------
- Plot3D_horizontalinterp(Plot3D *p3, int xmin, int xmax, int y,
- double z1, double z2, Pixel c1, Pixel c2)
-
- Draws a "Horizontal" line on the framebuffer between two screen coordinates,
- but also supplies z-values and zbuffering. Performs a color interpolation
- between c1 and c2. This is primarily used by the SolidTriangleInterp()
- function to give the illusion of smooth surfaces.
- -------------------------------------------------------------------------- */
-
-void Plot3D_horizontalinterp(Plot3D *p3, int xmin, int xmax, int y,
- Zvalue z1, Zvalue z2, Pixel c1, Pixel c2) {
- Pixel *p;
- FrameBuffer *f;
- int i;
- Zvalue *zbuf,z,mz;
- double mc;
- int startx, endx;
- double invdx;
-
- f = p3->frame;
- if ((y < f->ymin) || (y >= f->ymax)) return;
- if (xmin >= f->xmax) return;
- if (xmin < f->xmin) startx = f->xmin;
- else startx = xmin;
- if (xmax < f->xmin) return;
- if (xmax >= f->xmax) endx = f->xmax - 1;
- else endx = xmax;
-
- /* Calculate z slope */
- if (xmax != xmin) {
- invdx = 1.0/(double) (xmax-xmin);
- } else {
- invdx = 0;
- }
-
- mz = (Zvalue) (z2 - z1)*invdx;
-
- /* Calculate c slope */
-
- mc = (double) (c2 - c1)*invdx;
-
- /* Draw it */
-
- p = &f->pixels[y][startx];
- zbuf = &f->zbuffer[y][startx];
- for (i = startx; i <= endx; i++, p++, zbuf++) {
- z = (Zvalue) (mz*(i-xmin) + z1);
- if (z <= *zbuf) {
- *p = (Pixel) (mc*(i-xmin)+c1);
- *zbuf = z;
- }
- }
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_interptriangletransform(Plot3D *p3,
- int tx1, int ty2, Zvalue tz1, Pixel c1,
- int tx2, int ty2, Zvalue tz2, Pixel c2,
- int tx3, int ty3, Zvalue tz3, Pixel c3)
-
- This function draws a 3D z-buffered filled triangle with color
- interpolation. Assumes three points have already been transformed
- into screen coordinates.
-
- General idea :
- 1. Transform the three points into screen coordinates
- 2. Order three points vertically on screen.
- 3. Check for degenerate cases (where 3 points are colinear).
- 4. Fill in the resulting triangle using horizontal lines.
- 5. Colors are interpolated between end points
- -------------------------------------------------------------------------- */
-
-void Plot3D_interptriangletransform(Plot3D *p3,
- int tx1, int ty1, Zvalue tz1, Pixel c1,
- int tx2, int ty2, Zvalue tz2, Pixel c2,
- int tx3, int ty3, Zvalue tz3, Pixel c3) {
- int tempx, tempy;
- Zvalue tempz;
- double m1,m2,m3, mz1, mz2, mz3;
- double mc1,mc2,mc3;
- Pixel ic1,ic2,tempc;
- int y;
- int ix1, ix2;
- Zvalue zz1, zz2;
- FrameBuffer *f;
-
- f = p3->frame;
-
- /* Figure out which point has the greatest "y" value */
-
- if (ty2 > ty1) { /* Swap points 1 and 2 if 2 is higher */
- tempx = tx1;
- tempy = ty1;
- tempz = tz1;
- tempc = c1;
- tx1 = tx2;
- ty1 = ty2;
- tz1 = tz2;
- c1 = c2;
- tx2 = tempx;
- ty2 = tempy;
- tz2 = tempz;
- c2 = tempc;
- }
- if (ty3 > ty1) { /* Swap points 1 and 3 if 3 is higher */
- tempx = tx1;
- tempy = ty1;
- tempz = tz1;
- tempc = c1;
- tx1 = tx3;
- ty1 = ty3;
- tz1 = tz3;
- c1 = c3;
- tx3 = tempx;
- ty3 = tempy;
- tz3 = tempz;
- c3 = tempc;
- }
- if (ty3 > ty2) { /* Swap points 2 and 3 if 3 is higher */
- tempx = tx2;
- tempy = ty2;
- tempz = tz2;
- tempc = c2;
- tx2 = tx3;
- ty2 = ty3;
- tz2 = tz3;
- c2 = c3;
- tx3 = tempx;
- ty3 = tempy;
- tz3 = tempz;
- c3 = tempc;
- }
-
- /* Points are now order so that t_1 is the highest point, t_2 is the
- middle point, and t_3 is the lowest point */
-
- /* Check for degenerate cases here */
-
- if ((ty1 == ty2) && (ty2 == ty3)) {
-
- /* Points are aligned horizontally. Handle as a special case */
- /* Just draw three lines using the outline color */
-
- if (tx2 > tx1)
- Plot3D_horizontalinterp(p3,tx1,tx2,ty1,tz1,tz2,c1,c2);
- else
- Plot3D_horizontalinterp(p3,tx2,tx1,ty1,tz2,tz1,c2,c1);
- if (tx3 > tx1)
- Plot3D_horizontalinterp(p3,tx1,tx3,ty1,tz1,tz3,c1,c3);
- else
- Plot3D_horizontalinterp(p3,tx3,tx1,ty1,tz3,tz1,c3,c1);
- if (tx3 > tx2)
- Plot3D_horizontalinterp(p3,tx2,tx3,ty2,tz2,tz3,c2,c3);
- else
- Plot3D_horizontalinterp(p3,tx3,tx2,ty2,tz3,tz2,c3,c2);
-
- } else {
-
- /* First process line segments between (x1,y1)-(x2,y2)
- And between (x1,y1),(x3,y3) */
-
- if (ty2 < ty1) {
- m1 = (double) (tx2 - tx1)/(double) (ty2 - ty1);
- m2 = (double) (tx3 - tx1)/(double) (ty3 - ty1);
- mz1 = (tz2 - tz1)/(double) (ty2 - ty1);
- mz2 = (tz3 - tz1)/(double) (ty3 - ty1);
- mc1 = (c2 - c1)/(double) (ty2 - ty1);
- mc2 = (c3 - c1)/(double) (ty3 - ty1);
-
- y = ty1;
- while (y >= ty2) {
- /* Calculate x values from slope */
- ix1 = (int) (m1*(y-ty1)+0.5) + tx1;
- ix2 = (int) (m2*(y-ty1)+0.5) + tx1;
- zz1 = mz1*(y-ty1) + tz1;
- zz2 = mz2*(y-ty1) + tz1;
- ic1 = mc1*(y-ty1) + c1;
- ic2 = mc2*(y-ty1) + c1;
- if (ix1 > ix2)
- Plot3D_horizontalinterp(p3,ix2,ix1,y,zz2,zz1,ic2,ic1);
- else
- Plot3D_horizontalinterp(p3,ix1,ix2,y,zz1,zz2,ic1,ic2);
- y--;
- }
- }
- if (ty3 < ty2) {
- /* Draw lower half of the triangle */
- m2 = (double) (tx3 - tx1)/(double) (ty3 - ty1);
- mz2 = (tz3 - tz1)/(double) (ty3 - ty1);
- mc2 = (c3 - c1)/(double) (ty3 - ty1);
- m3 = (double) (tx3 - tx2)/(double)(ty3 - ty2);
- mz3 = (tz3 - tz2)/(double) (ty3 - ty2);
- mc3 = (c3 - c2)/(double) (ty3 - ty2);
- y = ty2;
- while (y >= ty3) {
- ix1 = (int) (m3*(y-ty2)+0.5)+tx2;
- ix2 = (int) (m2*(y-ty1)+0.5)+tx1;
- zz1 = mz3*(y-ty2)+tz2;
- zz2 = mz2*(y-ty1)+tz1;
- ic1 = mc3*(y-ty2)+c2;
- ic2 = mc2*(y-ty1)+c1;
- if (ix1 > ix2)
- Plot3D_horizontalinterp(p3,ix2,ix1,y,zz2,zz1,ic2,ic1);
- else
- Plot3D_horizontalinterp(p3,ix1,ix2,y,zz1,zz2,ic1,ic2);
- y--;
- }
- }
- }
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_interptriangle(Plot3D *p3,
- double x1, double y1, double z1, Pixel c1,
- double x2, double y2, double z2, Pixel c2,
- double x3, double y3, double z3, Pixel c3)
-
- This function draws a 3D z-buffered filled triangle with color
- interpolation.
-
- This function simply transforms the given points and calls
- Plot3D_InterpTriangleTransform().
- -------------------------------------------------------------------------- */
-
-void Plot3D_interptriangle(Plot3D *p3,
- double x1, double y1, double z1, Pixel c1,
- double x2, double y2, double z2, Pixel c2,
- double x3, double y3, double z3, Pixel c3) {
-
- int tx1, tx2, tx3, ty1, ty2, ty3;
- Zvalue tz1, tz2, tz3;
- GL_Vector t;
- double invw;
-
- /* Transform the three points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,x1,y1,z1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz1 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x2,y2,z2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz2 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x3,y3,z3,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx3 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty3 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz3 = (Zvalue) t.z;
-
- Plot3D_interptriangletransform(p3,tx1,ty1,tz1,c1,tx2,ty2,tz2,c2,tx3,ty3,tz3,c3);
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_quad(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- double x4, double y4, double z4,
- Pixel fillcolor)
-
- This function draws a 3D outlined Quadralateral. Used primarily for
- drawing meshes and other things.
-
- Plotting is done in the following order :
- (x1,y1,z1) --> (x2,y2,z2)
- (x2,y2,z2) --> (x3,y3,z3)
- (x3,y3,z3) --> (x4,y4,z4)
- (x4,y4,z4) --> (x1,y1,z1)
- -------------------------------------------------------------------------- */
-
-void Plot3D_quad(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- double x4, double y4, double z4,
- Pixel color) {
-
- int tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4;
- Zvalue tz1, tz2, tz3, tz4;
- GL_Vector t;
- double invw;
-
- /* Transform the three points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,x1,y1,z1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz1 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x2,y2,z2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz2 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x3,y3,z3,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx3 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty3 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz3 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x4,y4,z4,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx4 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty4 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz4 = (Zvalue) t.z;
-
- Plot3D_linetransform(p3,tx1,ty1,tz1,tx2,ty2,tz2,color);
- Plot3D_linetransform(p3,tx2,ty2,tz2,tx3,ty3,tz3,color);
- Plot3D_linetransform(p3,tx3,ty3,tz3,tx4,ty4,tz4,color);
- Plot3D_linetransform(p3,tx4,ty4,tz4,tx1,ty1,tz1,color);
-
-}
-
-
-/* -------------------------------------------------------------------------
- Plot3D_solidquad(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- double x4, double y4, double z4,
- Pixel fillcolor)
-
- This function draws a 3D solid Quadralateral. Uses the function
- Plot3D_SolidTriangleTransform() to fill in the region.
-
- Plotting is done in the following order :
- (x1,y1,z1) --> (x2,y2,z2)
- (x2,y2,z2) --> (x3,y3,z3)
- (x3,y3,z3) --> (x4,y4,z4)
- (x4,y4,z4) --> (x1,y1,z1)
- -------------------------------------------------------------------------- */
-
-void Plot3D_solidquad(Plot3D *p3, double x1, double y1, double z1,
- double x2, double y2, double z2,
- double x3, double y3, double z3,
- double x4, double y4, double z4,
- Pixel color) {
-
- int tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4;
- Zvalue tz1, tz2, tz3, tz4;
- GL_Vector t;
- double invw;
-
- /* Transform the three points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,x1,y1,z1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz1 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x2,y2,z2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz2 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x3,y3,z3,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx3 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty3 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz3 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x4,y4,z4,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx4 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty4 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz4 = (Zvalue) t.z;
-
- Plot3D_solidtriangletransform(p3,tx1,ty1,tz1,tx2,ty2,tz2,tx3,ty3,tz3,color);
- Plot3D_solidtriangletransform(p3,tx1,ty1,tz1,tx4,ty4,tz4,tx3,ty3,tz3,color);
-}
-
-/* -------------------------------------------------------------------------
- Plot3D_interpquad(Plot3D *p3, double x1, double y1, double z1, Pixel c1,
- double x2, double y2, double z2, Pixel c2,
- double x3, double y3, double z3, Pixel c3,
- double x4, double y4, double z4, Pixel c4)
-
- This function draws a 3D color-interpolated Quadralateral. Uses the function
- Plot3D_InterpTriangleTransform() to fill in the region.
-
- Plotting is done in the following order :
- (x1,y1,z1) --> (x2,y2,z2)
- (x2,y2,z2) --> (x3,y3,z3)
- (x3,y3,z3) --> (x4,y4,z4)
- (x4,y4,z4) --> (x1,y1,z1)
- -------------------------------------------------------------------------- */
-
-void Plot3D_interpquad(Plot3D *p3, double x1, double y1, double z1, Pixel c1,
- double x2, double y2, double z2, Pixel c2,
- double x3, double y3, double z3, Pixel c3,
- double x4, double y4, double z4, Pixel c4) {
-
-
- int tx1, tx2, tx3, tx4, ty1, ty2, ty3, ty4;
- Zvalue tz1, tz2, tz3, tz4;
- GL_Vector t;
- double invw;
-
- /* Transform the three points into screen coordinates */
-
- Matrix_transform4(p3->trans_mat,x1,y1,z1,1,&t); /* Point 1 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx1 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty1 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz1 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x2,y2,z2,1,&t); /* Point 2 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx2 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty2 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz2 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x3,y3,z3,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx3 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty3 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz3 = (Zvalue) t.z;
-
- Matrix_transform4(p3->trans_mat,x4,y4,z4,1,&t); /* Point 3 */
- invw = 1.0/t.w;
- t.x = t.x *invw;
- t.y = t.y *invw;
- t.z = t.z *invw;
- tx4 = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty4 = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz4 = (Zvalue) t.z;
-
- Plot3D_interptriangletransform(p3,tx1,ty1,tz1,c1,tx2,ty2,tz2,c2,tx3,ty3,tz3,c3);
- Plot3D_interptriangletransform(p3,tx1,ty1,tz1,c1,tx4,ty4,tz4,c4,tx3,ty3,tz3,c3);
-
-}
-
-/* --------------------------------------------------------------------------
- Plot3D_solidsphere(Plot3 *p3, double x, double y, double z, double radius,
- Pixel c)
-
- Makes a 3D sphere at x,y,z with given radius and color.
-
- Basic strategy :
- 1. Transform point to screen coordinates
- 2. Figure out what the radius is in screen coordinates
- 3. Use bresenham algorithm for large spheres
- 4. Use bitmaps for small spheres
- -------------------------------------------------------------------------- */
-
-/* This is used to fill in spheres */
-static int s_xmin;
-static int s_ymin;
-static int s_xmax;
-static int s_ymax;
-static Pixel **s_pixels;
-static Zvalue **s_zbuffer;
-
-void Plot3D_spherehorizontal(int xmin, int xmax, int y, Zvalue z, Pixel color) {
- int i;
- int startx, endx;
- Pixel *p;
- Zvalue *zbuf;
-
- if ((y < s_ymin) || (y >= s_ymax)) return;
- if (xmin < s_xmin) startx = s_xmin;
- else startx = xmin;
- if (xmax >= s_xmax) endx = s_xmax - 1;
- else endx = xmax;
-
- /* Draw it */
-
- p = &s_pixels[y][xmin];
- zbuf = &s_zbuffer[y][xmin];
- for (i = startx; i <= endx; i++, p++, zbuf++) {
- if (z <= *zbuf) {
- *p = color;
- *zbuf = z;
- }
- }
-}
-
-void Plot3D_solidsphere(Plot3D *p3, double x, double y, double z, double radius,
- Pixel c) {
-
- GL_Vector t,r;
- double rad;
- int tx,ty, irad;
- Zvalue tz;
- double invw;
- int ix, iy, ix1,ix2,p;
- FrameBuffer *f;
-
- /* First transform the point into model coordinates */
-
- Matrix_transform4(p3->fullmodel_mat,x,y,z,1,&t);
-
- /* Now transform two points in order to find proper sphere radius */
-
- Matrix_transform4(p3->view_mat,t.x+radius,t.y,t.z,t.w,&r); /* transform radius */
- Matrix_transform4(p3->view_mat,t.x,t.y,t.z,t.w,&t);
-
- invw = 1.0/t.w;
- t.x = t.x*invw;
- t.y = t.y*invw;
- t.z = t.z*invw;
- invw = 1.0/r.w;
- r.x = r.x*invw;
- r.y = r.y*invw;
- r.z = r.z*invw;
- invw = 1.0/r.w;
-
- rad = fabs(t.x - r.x);
-
- /* Transform everything into screen coordinates */
-
- tx = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz = (Zvalue) t.z;
- irad = (int) (p3->zoom*(rad*p3->width + 0.5));
-
- /* This is only a temporary solution (maybe). */
-
-#define fill_zcircle(x,y,c) \
- ix1 = tx - x; \
- ix2 = tx + x; \
- if (ix1 < s_xmin) ix1 = s_xmin; \
- if (ix2 >= s_xmax) ix2 = s_xmax; \
- Plot3D_spherehorizontal(ix1,ix2,y,tz,c);
-
- f = p3->frame;
- s_xmin = f->xmin;
- s_ymin = f->ymin;
- s_xmax = f->xmax;
- s_ymax = f->ymax;
- s_pixels = f->pixels;
- s_zbuffer = f->zbuffer;
- if (irad <= 1) {
- /* Plot a single pixel */
- if ((tx >= f->xmin) && (tx < f->xmax)) {
- if ((ty >= f->ymin) && (ty <f->ymax)) {
- if (tz <= f->zbuffer[ty][tx]) {
- f->pixels[ty][tx] = c;
- f->zbuffer[ty][tx] = tz;
- }
- }
- }
- return;
- }
- ix = 0;
- iy = irad;
- p = 3-2*irad;
- while (ix <= iy) {
- fill_zcircle(ix,ty+iy,c);
- fill_zcircle(ix,ty-iy,c);
- fill_zcircle(iy,ty+ix,c);
- fill_zcircle(iy,ty-ix,c);
- if (p < 0) p = p + 4*ix + 6;
- else {
- p = p + 4*(ix-iy) + 10;
- iy = iy -1;
- }
- ix++;
- }
-}
-
-
-/* --------------------------------------------------------------------
- Plot3D_outlinesphere(Plot3D *p3, double x, double y, double z,
- double radius, Pixel color, Pixel bc)
-
- Draws an outlined sphere.
- -------------------------------------------------------------------- */
-
-void Plot3D_outlinesphere(Plot3D *p3, double x, double y, double z,
- double radius, Pixel c, Pixel bc)
-{
- GL_Vector t,r;
- double rad;
- int tx,ty, irad;
- Zvalue tz;
- double invw;
- int ix, iy, ix1,ix2,p;
-
- FrameBuffer *f;
-
- /* First transform the point into model coordinates */
-
- Matrix_transform4(p3->fullmodel_mat,x,y,z,1,&t);
-
- /* Now transform two points in order to find proper sphere radius */
-
- Matrix_transform4(p3->view_mat,t.x+radius,t.y,t.z,t.w,&r); /* transform radius */
- Matrix_transform4(p3->view_mat,t.x,t.y,t.z,t.w,&t);
-
- invw = 1.0/t.w;
- t.x = t.x*invw;
- t.y = t.y*invw;
- t.z = t.z*invw;
- invw = 1.0/r.w;
- r.x = r.x*invw;
- r.y = r.y*invw;
- r.z = r.z*invw;
- invw = 1.0/r.w;
-
- rad = fabs(t.x - r.x);
-
- /* Transform everything into screen coordinates */
-
- tx = (int) ((t.x +p3->xshift)*p3->zoom*p3->width + 0.5) + p3->view_xmin;
- ty = (int) ((t.y +p3->yshift)*p3->zoom*p3->height + 0.5) + p3->view_ymin;
- tz = (Zvalue) t.z;
- irad = (int) (p3->zoom*(rad*p3->width + 0.5));
-
- /* This is only a temporary solution (maybe). */
-#define plot_zcircle(x,y,c) \
- if ((x >= s_xmin) && (x < s_xmax) && \
- (y >= s_ymin) && (y < s_ymax)) {\
- if (tz <= s_zbuffer[y][x]) { \
- s_pixels[y][x] = c; \
- s_zbuffer[y][x] = tz; } \
- }
-
- f = p3->frame;
- s_xmin = f->xmin;
- s_ymin = f->ymin;
- s_xmax = f->xmax;
- s_ymax = f->ymax;
- s_pixels = f->pixels;
- s_zbuffer = f->zbuffer;
-
- if (irad <= 1) {
- /* Plot a single pixel */
- if ((tx >= f->xmin) && (tx < f->xmax)) {
- if ((ty >= f->ymin) && (ty <f->ymax)) {
- if (tz <= f->zbuffer[ty][tx]) {
- f->pixels[ty][tx] = c;
- f->zbuffer[ty][tx] = tz;
- }
- }
- }
- return;
- }
- ix = 0;
- iy = irad;
- p = 3-2*irad;
- while (ix <= iy) {
- fill_zcircle(ix,ty+iy,c);
- fill_zcircle(ix,ty-iy,c);
- fill_zcircle(iy,ty+ix,c);
- fill_zcircle(iy,ty-ix,c);
-
- plot_zcircle(tx+ix,ty+iy,bc);
- plot_zcircle(tx-ix,ty+iy,bc);
- plot_zcircle(tx+ix,ty-iy,bc);
- plot_zcircle(tx-ix,ty-iy,bc);
- plot_zcircle(tx+iy,ty+ix,bc);
- plot_zcircle(tx-iy,ty+ix,bc);
- plot_zcircle(tx+iy,ty-ix,bc);
- plot_zcircle(tx-iy,ty-ix,bc);
- if (p < 0) p = p + 4*ix + 6;
- else {
- p = p + 4*(ix-iy) + 10;
- iy = iy -1;
- }
- ix++;
- }
-}
-
-/* QUAD Test
- Test out quad functions for graphing */
-
-double zf(double x, double y) {
- return cos(sqrt(x*x + y*y)*10.0)/(sqrt(x*x+y*y)+1);
-}
-
-void Quad_Test(Plot3D *p3, int npoints) {
- int i,j;
- double dx;
- double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,za;
- int c;
- dx = 2.0/npoints;
-
-
- for (i = 0; i < npoints; i++)
- for (j = 0; j < npoints; j++) {
- x1 = i*dx + -1.0;
- y1 = j*dx + -1.0;
- x2 = x1 + dx;
- x3 = x1 + dx;
- x4 = x1;
- y2 = y1;
- y3 = y1 + dx;
- y4 = y1 + dx;
- z1 = zf(x1,y1);
- z2 = zf(x2,y2);
- z3 = zf(x3,y3);
- z4 = zf(x4,y4);
- za = 0.25*(z1+z2+z3+z4);
- c = 16+((za + 1)*120);
- if (c > 254) c = 254;
- Plot3D_quad(p3,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,(Pixel) c);
- }
-}
-
-
-void Quad_SolidTest(Plot3D *p3, int npoints) {
- int i,j;
- double dx;
- double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,za;
- int c;
- dx = 2.0/npoints;
-
-
- for (i = 0; i < npoints; i++)
- for (j = 0; j < npoints; j++) {
- x1 = i*dx + -1.0;
- y1 = j*dx + -1.0;
- x2 = x1 + dx;
- x3 = x1 + dx;
- x4 = x1;
- y2 = y1;
- y3 = y1 + dx;
- y4 = y1 + dx;
- z1 = zf(x1,y1);
- z2 = zf(x2,y2);
- z3 = zf(x3,y3);
- z4 = zf(x4,y4);
- za = 0.25*(z1+z2+z3+z4);
- c = 16+((za + 1)*120);
- if (c > 254) c = 254;
- Plot3D_solidquad(p3,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,(Pixel) c);
- }
-}
-
-
-
-void Quad_InterpTest(Plot3D *p3, int npoints) {
- int i,j;
- double dx;
- double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4;
- int c1,c2,c3,c4;
- dx = 2.0/npoints;
-
-
- for (i = 0; i < npoints; i++)
- for (j = 0; j < npoints; j++) {
- x1 = i*dx + -1.0;
- y1 = j*dx + -1.0;
- x2 = x1 + dx;
- x3 = x1 + dx;
- x4 = x1;
- y2 = y1;
- y3 = y1 + dx;
- y4 = y1 + dx;
- z1 = zf(x1,y1);
- z2 = zf(x2,y2);
- z3 = zf(x3,y3);
- z4 = zf(x4,y4);
- c1 = 16+((z1 + 1)*120);
- c2 = 16+((z2 + 1)*120);
- c3 = 16+((z3 + 1)*120);
- c4 = 16+((z4 + 1)*120);
- if (c1 > 254) c1 = 254;
- if (c2 > 254) c2 = 254;
- if (c3 > 254) c3 = 254;
- if (c4 > 254) c4 = 254;
- Plot3D_interpquad(p3,x1,y1,z1,(Pixel) c1,x2,y2,z2,(Pixel) c2,x3,y3,z3,(Pixel) c3,x4,y4,z4,(Pixel) c4);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-