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