From anonymous, 11 Months 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. }