void clip(double x0, double y0, double x1, double y1) { outcode outcode0, outcode1, outcodeOut; int accept = FALSE, done = FALSE; outcode0 = CompOutCode(x0, y0); outcode1 = CompOutCode(x1, y1); do { if (!(outcode0 | outcode1)) { accept = TRUE; done = TRUE; } else if (outcode0 & outcode1) done = TRUE; else { double x, y; outcodeOut = outcode0 ? outcode0 : outcode1; if (outcodeOut & TOP) { x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0); y = ymax; } else if (outcodeOut & BOTTOM) { x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymin; } else if (outcodeOut & RIGHT) { y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); x = xmax; } else { y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); x = xmin; } if (outcodeOut == outcode0) { x0 = x; y0 = y; outcode0 = CompOutCode(x0, y0); } else { x1 = x; y1 = y; outcode1 = CompOutCode(x1, y1); } } } while (done == FALSE); if (accept) line(x0, y0, x1, y1); rectangle(xmin, ymin, xmax, ymax); }
ClipResult cohen_sutherland_line_clip_d (double *x0, double *y0, double *x1, double *y1, double xmin_, double xmax_, double ymin_, double ymax_) { /* Cohen-Sutherland clipping algorithm for line P0=(x1,y0) to P1=(x1,y1) and clip rectangle with diagonal from (xmin,ymin) to (xmax,ymax).*/ struct LOC_cohen_sutherland_line_clip V; int accept = CFALSE, done = CFALSE; ClipResult clip = Visible; outcode outcode0, outcode1, outcodeOut; /*Outcodes for P0,P1, and whichever point lies outside the clip rectangle*/ double x=0., y=0.; V.xmin = xmin_; V.xmax = xmax_; V.ymin = ymin_; V.ymax = ymax_; CompOutCode(*x0, *y0, &outcode0, &V); CompOutCode(*x1, *y1, &outcode1, &V); do { if (outcode0 == 0 && outcode1 == 0) { /*Trivial accept and exit*/ accept = CTRUE; done = CTRUE; } else if ((outcode0 & outcode1) != 0) { clip = Invisible; done = CTRUE; } /*Logical intersection is true, so trivial reject and exit.*/ else { clip = Visible; /*Failed both tests, so calculate the line segment to clip; from an outside point to an intersection with clip edge.*/ /*At least one endpoint is outside the clip rectangle; pick it.*/ if (outcode0 != 0) outcodeOut = outcode0; else outcodeOut = outcode1; /*Now find intersection point; use formulas y=y0+slope*(x-x0),x=x0+(1/slope)*(y-y0).*/ if (((1L << ((long)TOP)) & outcodeOut) != 0) { /*Divide line at top of clip rectangle*/ x = *x0 + (*x1 - *x0) * (V.ymax - *y0) / (*y1 - *y0); y = V.ymax; } else if (((1L << ((long)BOTTOM)) & outcodeOut) != 0) { /*Divide line at bottom of clip rectangle*/ x = *x0 + (*x1 - *x0) * (V.ymin - *y0) / (*y1 - *y0); y = V.ymin; } else if (((1L << ((long)RIGHT)) & outcodeOut) != 0) { /*Divide line at right edge of clip rectangle*/ y = *y0 + (*y1 - *y0) * (V.xmax - *x0) / (*x1 - *x0); x = V.xmax; } else if (((1L << ((long)LEFT)) & outcodeOut) != 0) { /*Divide line at left edge of clip rectangle*/ y = *y0 + (*y1 - *y0) * (V.xmin - *x0) / (*x1 - *x0); x = V.xmin; } /*Now we move outside point to intersection point to clip, and get ready for next pass.*/ if (outcodeOut == outcode0) { *x0 = x; *y0 = y; CompOutCode(*x0, *y0, &outcode0, &V); } else { *x1 = x; *y1 = y; CompOutCode(*x1, *y1, &outcode1, &V); } } } while (!done); return clip; }