www.pudn.com > CG2Programs.rar > clipLiangBarsky.c
/* clipLiangBarsky, Chapter 6, pp. 231-232 */
/* EXAMPLE STARTS HERE */
#include "graphics.h"
#define ROUND(a) ((int)(a+0.5))
int clipTest (float p, float q, float * u1, float * u2)
{
float r;
int retVal = TRUE;
if (p < 0.0) {
r = q / p;
if (r > *u2)
retVal = FALSE;
else
if (r > *u1)
*u1 = r;
}
else
if (p > 0.0) {
r = q / p;
if (r < *u1)
retVal = FALSE;
else if (r < *u2)
*u2 = r;
}
else
/* p = 0, so line is parallel to this clipping edge */
if (q < 0.0)
/* Line is outside clipping edge */
retVal = FALSE;
return (retVal);
}
void clipLine (dcPt winMin, dcPt winMax, wcPt2 p1, wcPt2 p2)
{
float u1 = 0.0, u2 = 1.0, dx = p2.x - p1.x, dy;
if (clipTest (-dx, p1.x - winMin.x, &u1, &u2))
if (clipTest (dx, winMax.x - p1.x, &u1, &u2)) {
dy = p2.y - p1.y;
if (clipTest (-dy, p1.y - winMin.y, &u1, &u2))
if (clipTest (dy, winMax.y - p1.y, &u1, &u2)) {
if (u2 < 1.0) {
p2.x = p1.x + u2 * dx;
p2.y = p1.y + u2 * dy;
}
if (u1 > 0.0) {
p1.x += u1 * dx;
p1.y += u1 * dy;
}
lineDDA (ROUND(p1.x), ROUND(p1.y), ROUND(p2.x), ROUND(p2.y));
}
}
}
/* EXAMPLE ENDS HERE */
#define N_PTS 5
void main (int argc, char ** argv)
{
wcPt2 pts[N_PTS] =
{ 60, 20, 375, 80, 280, 280, 100, 280, 100, 100 };
dcPt winMin = { 50, 50 };
dcPt winMax = { 350, 250 };
wcPt2 winPts[5];
int i;
long windowID = openGraphics (*argv, 400, 300);
setBackground (WHITE);
/* For illustration, draw the clipping rectangle */
winPts[0].x = winMin.x; winPts[0].y = winMin.y;
winPts[1].x = winMax.x; winPts[1].y = winMin.y;
winPts[2].x = winMax.x; winPts[2].y = winMax.y;
winPts[3].x = winMin.x; winPts[3].y = winMax.y;
winPts[4].x = winMin.x; winPts[4].y = winMin.y;
setColor (BLUE);
pPolyline (5, winPts);
/* For illustration, draw the complete set of lines */
setColor (GREEN);
pPolyline (N_PTS, pts);
/* Clip pairs of points and draw line segments */
setColor (BLACK);
for (i=0; i