home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
505a.lha
/
GrapicsGems
/
2DClip
/
clip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-01
|
3KB
|
178 lines
/*
* file clip.c
* contains the actual clipping routines
*/
#include <stdio.h>
#include "GraphicsGems.h"
#include "line.h"
/*
* vis_vector
*
* PURPOSE
* actual user interface. Draws a clipped line
* NOTE: coordinates are given in converted LONGS!
*
* xf, yf from coordinates of vector to be drawn
* xt, yt to coordinates of vector to be drawn
*/
vis_vector(xf, yf, xt, yt)
long xf, yf, xt, yt;
{
SEGMENT l;
if(xf == xt && yf == yt)
return;
l._from._x = xf;
l._from._y = yf;
l._to._x = xt;
l._to._y = yt;
/*
* start at top of list
*/
clip(CL, &l);
}
/*
* clip
*
* PURPOSE
*
* p pointer to polygon
* l pointer to line segment
*/
clip(p, l)
CONTOUR *p;
SEGMENT *l;
{
SEGMENT *sp, ss;
CLIST *sol;
POINT pt;
boolean up, delay, inside, p_inside(), disjunct();
int i;
short nsol, nsmax = 2;
/*
* list exhausted do what you like
* we want to plot
*/
if(p == (CONTOUR *)NULL) {
move((l->_from._x), (l->_from._y));
cont((l->_to._x), (l->_to._y));
return;
}
/*
* polygon is switched off
* take next one
*/
if(!IS_ON(p)) {
clip(p->_next, l);
return;
}
/*
* comparison on basis of the
* enclosing rectangle
*/
if(disjunct(p, l)) {
if(!IS_NORMAL(p)) {
clip(p->_next, l);
}
return;
}
/*
* calculate possible intersections
*/
sol = (CLIST *) calloc(2, sizeof(CLIST));
sol[0]._p._x = l->_from._x;
sol[0]._p._y = l->_from._y;
sol[0]._type = STD;
sol[1]._p._x = l->_to._x;
sol[1]._p._y = l->_to._y;
sol[1]._type = STD;
nsol = 2;
cross_calc(p, l, &sol, &nsol, nsmax);
pt._x = sol[0]._p._x;
pt._y = sol[0]._p._y;
/*
* determine status of first point
*/
inside = p_inside(p, &pt);
if((!inside && IS_NORMAL(p)) || (inside && !IS_NORMAL(p)))
up = TRUE;
else
up = FALSE;
delay = FALSE;
/*
* process list of intersections
*/
for(i=1; i<nsol; i++) {
if(!up) {
ss._from._x = sol[i-1]._p._x;
ss._from._y = sol[i-1]._p._y;
ss._to._x = sol[i]._p._x;
ss._to._y = sol[i]._p._y;
clip(p->_next, &ss);
}
if(!delay) {
if(sol[i]._type != DELAY)
up = (up) ? FALSE : TRUE;
else
delay = TRUE;
}
else {
up = (up) ? FALSE : TRUE;
delay = FALSE;
}
}
free(sol);
}
/*
* disjunct
*
* PURPOSE
* determine if the box enclosing the polygon
* stored in p and the box enclosing the line
* segment stored in l are disjunct.
* Return TRUE if disjunct else FALSE
*
* p points to the polygon structure
* l points to the linesegment structure
*
*/
boolean disjunct(p, l)
CONTOUR *p;
SEGMENT *l;
{
if((max(l->_from._x, l->_to._x) < p->_minx) ||
(min(l->_from._x, l->_to._x) > p->_maxx) ||
(max(l->_from._y, l->_to._y) < p->_miny) ||
(min(l->_from._y, l->_to._y) > p->_maxy) )
return(TRUE);
else
return(FALSE);
}
#define DEBUG
#ifdef DEBUG
move(x, y)
long x, y;
{
printf("(%d,%d) ->", x, y);
}
cont(x, y)
long x, y;
{
printf("(%d,%d)\n", x, y);
}
#endif