home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
macvglph.cpt
/
MacVogl-alpha1
/
clip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-17
|
3KB
|
147 lines
#include "vogl.h"
static int planes[] = {'\01', '\02', '\04', '\010', '\020', '\040'};
double wc[2][6];
/*
* clip
*
* Clips a 3D line using Homogeneous clipping.
* Reference: Newman and Sproull
*
*/
void
clip(p0, p1)
register Vector p0, p1;
{
double t, t1, t2, dx, dy, dz, dw;
int vx, vy, c1, c2, i;
c1 = MakeEdgeCoords(0, p0);
c2 = MakeEdgeCoords(1, p1);
if (!(c1 & c2)) {
t1 = 0.0;
t2 = 1.0;
for (i = 0; i < 6; i++)
if (wc[0][i] < 0.0 || wc[1][i] < 0.0) {
t = wc[0][i] / (wc[0][i] - wc[1][i]);
if (wc[0][i] < 0.0) {
if (t > t1)
t1 = t;
} else if (t < t2)
t2 = t;
}
if (t2 >= t1) {
vdevice.cpVvalid = 1;
dx = p1[V_X] - p0[V_X];
dy = p1[V_Y] - p0[V_Y];
dz = p1[V_Z] - p0[V_Z];
dw = p1[V_W] - p0[V_W];
if (t2 != 1.0) {
p1[V_X] = p0[V_X] + t2 * dx;
p1[V_Y] = p0[V_Y] + t2 * dy;
p1[V_Z] = p0[V_Z] + t2 * dz;
p1[V_W] = p0[V_W] + t2 * dw;
vdevice.cpVvalid = 0;
}
if (t1 != 0.0) {
p0[V_X] = p0[V_X] + t1 * dx;
p0[V_Y] = p0[V_Y] + t1 * dy;
p0[V_Z] = p0[V_Z] + t1 * dz;
p0[V_W] = p0[V_W] + t1 * dw;
}
vdevice.cpVx = WtoVx(p0);
vdevice.cpVy = WtoVy(p0);
vx = WtoVx(p1);
vy = WtoVy(p1);
(*vdevice.dev.Vdraw)(vx, vy);
vdevice.cpVx = vx;
vdevice.cpVy = vy;
}
}
}
/*
* MakeEdgeCoords
*
* calculates distance from point to each clipping plane in Homogeneous
* clipping coordinates. Return code if on outside of any clipping plane
*
*/
int
MakeEdgeCoords(i, p)
int i;
Vector p;
{
int j, k = 0;
wc[i][0] = p[V_W] + p[V_X];
wc[i][1] = p[V_W] - p[V_X];
wc[i][2] = p[V_W] + p[V_Y];
wc[i][3] = p[V_W] - p[V_Y];
wc[i][4] = p[V_W] + p[V_Z];
wc[i][5] = p[V_W] - p[V_Z];
for (j = 0; j < 6; j++)
if (wc[i][j] < 0.0)
k |= planes[j];
return(k);
}
/*
* quickclip
*
* A variation on the above that assumes p0 is a valid position in device coords
*
*/
void
quickclip(p0, p1)
register Vector p0, p1;
{
register double t, t1;
register int vx, vy, i;
t1 = 1.0;
wc[0][0] = p0[V_W] + p0[V_X];
wc[0][1] = p0[V_W] - p0[V_X];
wc[0][2] = p0[V_W] + p0[V_Y];
wc[0][3] = p0[V_W] - p0[V_Y];
wc[0][4] = p0[V_W] + p0[V_Z];
wc[0][5] = p0[V_W] - p0[V_Z];
wc[1][0] = p1[V_W] + p1[V_X];
wc[1][1] = p1[V_W] - p1[V_X];
wc[1][2] = p1[V_W] + p1[V_Y];
wc[1][3] = p1[V_W] - p1[V_Y];
wc[1][4] = p1[V_W] + p1[V_Z];
wc[1][5] = p1[V_W] - p1[V_Z];
for (i = 0; i < 6; i++)
if (wc[0][i] >= 0.0 && wc[1][i] < 0.0) {
t = wc[0][i] / (wc[0][i] - wc[1][i]);
if (t < t1)
t1 = t;
}
vdevice.cpVvalid = 1;
if (t1 != 1.0) {
p1[V_X] = p0[V_X] + t1 * (p1[V_X] - p0[V_X]);
p1[V_Y] = p0[V_Y] + t1 * (p1[V_Y] - p0[V_Y]);
p1[V_Z] = p0[V_Z] + t1 * (p1[V_Z] - p0[V_Z]);
p1[V_W] = p0[V_W] + t1 * (p1[V_W] - p0[V_W]);
vdevice.cpVvalid = 0;
}
vx = WtoVx(p1);
vy = WtoVy(p1);
(*vdevice.dev.Vdraw)(vx, vy);
vdevice.cpVx = vx;
vdevice.cpVy = vy;
}