/* ____________________ clipping This program illustrates the Cohen Sutherland clipping algorithm using sample C code. */ /* ____________________ includes, defines, types, prototypes */ #include #define TRUE 1 #define FALSE 0 typedef struct /* a rectangle in world coordinates */ { double top, left, bottom, right; } windRect ; int code(double x, double y); int clip(double *x1, double *y1, double *x2, double *y2); void setWindow(double top, double left, double bottom, double right); void setScale(void); windRect _window; /* the window */ double _windowCenterx, _windowCentery; /* ______________________________________________________________ setWindow This function sets a global variable, named _window. _window is a rectangle of type windRect. */ void setWindow(double top, double left, double bottom, double right) { _window.top = top; _window.left = left; _window.bottom = bottom; _window.right = right; _windowCenterx = (_window.left + _window.right) / 2.0; _windowCentery = (_window.top + _window.bottom) / 2.0; /* setScale();*/ } /* End of setWindow */ /* ____________________ main This program ... Arguments: argc argument count argv array of pointers to arguments Returns: Side Effects: Problems: */ main(int argc, char *argv) { double x, y, x1, y1; setWindow(0.0, 0.0, 100.0, 100.0); x = 50.0; y = 50.0; x1 = 150.0; y1 = 50.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = -50.0; y = 50.0; x1 = 150.0; y1 = 50.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 50.0; y1 = 50.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 140.0; y1 = 0.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 50.0; y1 = 50.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 50.0; x1 = 60.0; y1 = 60.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 50.0; y1 = 50.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 50.0; y1 = -150.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); x = 50.0; y = 150.0; x1 = 160.0; y1 = 60.0; printf("x=%lf y=%lf x1=%lf y1=%lf\n", x, y, x1, y1); if(clip(&x, &y, &x1, &y1)) printf("x=%lf y=%lf x1=%lf y1=%lf\n\n", x, y, x1, y1); } /* End of main */ /* ____________________ code This function computes the 4 bit patterns which classify points as to which of the 9 regions of the plane they reside. Arguments: x a double y a double Returns: an int containing the 4 bit pattern Side Effects: none Problems: none */ int code(double x, double y) { return (x < _window.left) << 3 | (x > _window.right) << 2 | (y < _window.top) << 1 | (y > _window.bottom); } /* End of code */ /* ____________________ clip This function implements the Cohen Sutherland clipping algorithm Arguments: x1 pointer to a double y1 pointer to a double x2 pointer to a double y2 pointer to a double Returns: the clipped values Side Effects: changes its arguments Problems: none */ int clip(double *x1, double *y1, double *x2, double *y2) { int c1 = code(*x1, *y1), c2 = code(*x2, *y2); double dx, dy; while(c1 | c2) { if(c1 & c2) return FALSE; dx = *x2 - *x1; dy = *y2 - *y1; if(c1) { if(c1 & 8) { *y1 += dy * (_window.left-*x1)/dx; *x1 = _window.left; } else if(c1 & 4) { *y1 += dy * (_window.right-*x1)/dx; *x1 = _window.right; } else if(c1 & 2) { *x1 += dx * (_window.top-*y1)/dy; *y1 = _window.top; } else if(c1 & 1) { *x1 += dx * (_window.bottom-*y1)/dy; *y1 = _window.bottom; } c1 = code(*x1, *y1); } else { if(c2 & 8) { *y2 += dy * (_window.left-*x2)/dx; *x2 = _window.left; } else if(c2 & 4) { *y2 += dy * (_window.right-*x2)/dx; *x2 = _window.right; } else if(c2 & 2) { *x2 += dx * (_window.top-*y2)/dy; *y2 = _window.top; } else if(c2 & 1) { *x2 += dx * (_window.bottom-*y2)/dy; *y2 = _window.bottom; } c2 = code(*x2, *y2); } } return TRUE; } /* End of clip */