원본 : http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
선 클리핑 알고리즘인 Cohen–Sutherland algorithm.
선을 그릴때 화면을 벗어났는지 체크하고 벗어났으면 화면 끝으로 점의 위치를 맞춰주는 알고리즘.
소프트웨어 렌더링을 할때 자주 사용된다.
Wiki에 정리가 잘 되어 있어서 올린다.
Cohen–Sutherland algorithm
In computer graphics, the Cohen–Sutherland algorithm (named after Danny Cohen and Ivan Sutherland) is a line clipping algorithm. The algorithm divides a 2D space into 9 regions, of which only the middle part (viewport) is visible.
In 1967, flight simulation work by Danny Cohen led to the development of the Cohen–Sutherland computer graphics two and three dimensional line clipping algorithms, created with Ivan Sutherland.[1]
[edit]The algorithm
The algorithm includes, excludes or partially includes the line based on where:
- Both endpoints are in the viewport region (bitwise OR of endpoints == 0): trivial accept.
- Both endpoints are on the same non-visible region (bitwise AND of endpoints != 0): trivial reject.
- Both endpoints are in different regions: In case of this non trivial situation the algorithm finds one of the two points that is outside the viewport region (there will be at least one point outside). The intersection of the outpoint and extended viewport border is then calculated (i.e. with the parametric equation for the line) and this new point replaces the outpoint. The algorithm repeats until a trivial accept or reject occurs.
The numbers in the figure below are called outcodes. An outcode is computed for each of the two points in the line. The first bit is set to 1 if the point is above the viewport. The bits in the outcode represent: Top, Bottom, Right, Left. For example the outcode 1010 represents a point that is top-right of the viewport. Note that the outcodes for endpoints must be recalculated on each iteration after the clipping occurs.
1001 | 1000 | 1010 |
0001 | 0000 | 0010 |
0101 | 0100 | 0110 |
The Cohen–Sutherland Algorithm can be used only on a rectangular clipping area . For other convex polygon clipping windows, use Cyrus–Beck Algorithm.
[edit]Example C/C++ implementation
typedef int OutCode; const int INSIDE = 0; // 0000 const int LEFT = 1; // 0001 const int RIGHT = 2; // 0010 const int BOTTOM = 4; // 0100 const int TOP = 8; // 1000 // Compute the bit code for a point (x, y) using the clip rectangle // bounded diagonally by (xmin, ymin), and (xmax, ymax) // ASSUME THAT xmax , xmin , ymax and ymin are global constants. OutCode ComputeOutCode(double x, double y) { OutCode code; code = INSIDE; // initialised as being inside of clip window if (x < xmin) // to the left of clip window code |= LEFT; else if (x > xmax) // to the right of clip window code |= RIGHT; if (y < ymin) // below the clip window code |= BOTTOM; else if (y > ymax) // above the clip window code |= TOP; return code; } // Cohen–Sutherland clipping algorithm clips a line from // P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with // diagonal from (xmin, ymin) to (xmax, ymax). void CohenSutherlandLineClipAndDraw(double x0, double y0, double x1, double y1) { // compute outcodes for P0, P1, and whatever point lies outside the clip rectangle OutCode outcode0 = ComputeOutCode(x0, y0); OutCode outcode1 = ComputeOutCode(x1, y1); bool accept = false; while (true) { if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop accept = true; break; } else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop break; } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge double x, y; // At least one endpoint is outside the clip rectangle; pick it. OutCode outcodeOut = outcode0? outcode0 : outcode1; // Now find the intersection point; // use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0) if (outcodeOut & TOP) { // point is above the clip rectangle x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0); y = ymax; } else if (outcodeOut & BOTTOM) { // point is below the clip rectangle x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0); y = ymin; } else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0); x = xmax; } else if (outcodeOut & LEFT) { // point is to the left of clip rectangle y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0); x = xmin; } //NOTE:***************************************************************************************** /* if you follow this algorithm exactly(at least for c#), then you will fall into an infinite loop in case a line crosses more than two segments. to avoid that problem, leave out the last else if(outcodeOut & LEFT) and just make it else*/ //********************************************************************************************** // Now we move outside point to intersection point to clip // and get ready for next pass. if (outcodeOut == outcode0) { x0 = x; y0 = y; outcode0 = ComputeOutCode(x0, y0); } else { x1 = x; y1 = y; outcode1 = ComputeOutCode(x1, y1); } } } if (accept) { // Following functions are left for implementation by user based on his platform(OpenGL/graphics.h etc.) DrawRectangle(xmin, ymin, xmax, ymax); LineSegment(x0, y0, x1, y1); } }
[edit]Notes
- ^ Principles of Interactive Computer Graphics p.124 and p.252, by Bob Sproull and William M. Newman, 1973, McGraw–Hill Education, International edition, ISBN 0-07-085535-8
[edit]See also
Algorithms used for the same purpose:
[edit]References
- James D. Foley. Computer graphics: principles and practice. Addison-Wesley Professional, 1996. p. 113.
[edit]External links
'프로그래밍 > 소프트웨어 렌더링' 카테고리의 다른 글
Tricks of the 3d game programming gurus Advanced (0) | 2012.08.29 |
---|---|
소프트웨어 렌더링 공개 소스 코드 (0) | 2011.08.17 |
Bresenham 알고리즘을 이용한 선 그리기 (0) | 2011.05.21 |
Clear함수 구현 (0) | 2011.05.17 |
시작하기 (0) | 2011.05.16 |