From anonymous, 4 Years ago, written in Java.
Embed
  1. int INSIDE = 0; // 0000
  2. int LEFT = 0x0001;   // 0001
  3. int RIGHT = 0x0010;  // 0010
  4. int BOTTOM = 0x0100; // 0100
  5. int TOP = 0x1001;    // 1000
  6. int xmin;
  7. int xmax;
  8. int ymin;
  9. int ymax;
  10.  
  11. // Compute the bit code for a point (x, y) using the clip rectangle
  12. // bounded diagonally by (xmin, ymin), and (xmax, ymax)
  13.  
  14. // ASSUME THAT xmax, xmin, ymax and ymin are global constants.
  15.  
  16. int ComputeOutCode(double x, double y)
  17. {
  18.   int code;
  19.  
  20.   code = INSIDE;          // initialised as being inside of [[clip window]]
  21.  
  22.   if (x < xmin)           // to the left of clip window
  23.     code |= LEFT;
  24.   else if (x > xmax)      // to the right of clip window
  25.     code |= RIGHT;
  26.   if (y < ymin)           // below the clip window
  27.     code |= BOTTOM;
  28.   else if (y > ymax)      // above the clip window
  29.     code |= TOP;
  30.  
  31.   return code;
  32. }
  33.  
  34. // Cohen–Sutherland clipping algorithm clips a line from
  35. // P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
  36. // diagonal from (xmin, ymin) to (xmax, ymax).
  37. void CohenSutherlandLineClipAndDraw(double x0, double y0, double x1, double y1)
  38. {
  39.   // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
  40.   int outcode0 = ComputeOutCode(x0, y0);
  41.   int outcode1 = ComputeOutCode(x1, y1);
  42.   boolean accept = false;
  43.  
  44.   while (true) {
  45.     if ((outcode0 | outcode1) == 0) {
  46.       // bitwise OR is 0: both points inside window; trivially accept and exit loop
  47.       accept = true;
  48.       break;
  49.     } else if ((outcode0 & outcode1) != 0) {
  50.       // bitwise AND is not 0: both points share an outside zone (LEFT, RIGHT, TOP,
  51.       // or BOTTOM), so both must be outside window; exit loop (accept is false)
  52.       break;
  53.     } else {
  54.       // failed both tests, so calculate the line segment to clip
  55.       // from an outside point to an intersection with clip edge
  56.       double x, y;
  57.  
  58.       // At least one endpoint is outside the clip rectangle; pick it.
  59.       int outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0;
  60.  
  61.       // Now find the intersection point;
  62.       // use formulas:
  63.       //   slope = (y1 - y0) / (x1 - x0)
  64.       //   x = x0 + (1 / slope) * (ym - y0), where ym is ymin or ymax
  65.       //   y = y0 + slope * (xm - x0), where xm is xmin or xmax
  66.       // No need to worry about divide-by-zero because, in each case, the
  67.       // outcode bit being tested guarantees the denominator is non-zero
  68.       if ((outcodeOut & TOP) != 0) {           // point is above the clip window
  69.         x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
  70.         y = ymax;
  71.       } else if ((outcodeOut & BOTTOM) != 0) { // point is below the clip window
  72.         x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
  73.         y = ymin;
  74.       } else if ((outcodeOut & RIGHT) != 0) {  // point is to the right of clip window
  75.         y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
  76.         x = xmax;
  77.       } else if ((outcodeOut & LEFT) != 0) {   // point is to the left of clip window
  78.         y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
  79.         x = xmin;
  80.       }
  81.  
  82.       // Now we move outside point to intersection point to clip
  83.       // and get ready for next pass.
  84.       if (outcodeOut == outcode0) {
  85.         x0 = x;
  86.         y0 = y;
  87.         outcode0 = ComputeOutCode(x0, y0);
  88.       } else {
  89.         x1 = x;
  90.         y1 = y;
  91.         outcode1 = ComputeOutCode(x1, y1);
  92.       }
  93.     }
  94.   }
  95.   if (accept) {
  96.     // Following functions are left for implementation by user based on
  97.     // their platform (OpenGL/graphics.h etc.)
  98.     DrawRectangle(xmin, ymin, xmax, ymax);
  99.     LineSegment(x0, y0, x1, y1);
  100.   }
  101. }