Index of this blog's computer graphics series:
Address: Index of related articles in computer graphics series (continuous update)
Reference material: Computer Graphics Machinery Industry Press, edited by Xu wenpeng
Experiment content: uses the Cohen-Sutherland encoding and cropping algorithm to crop a straight line with a rectangle frame.
The experiment code is as follows (debugged ):
# Include <Gl/glut. h> # include <stdio. h> # include <stdlib. h> # pragma comment (Lib, "opengl32.lib") # pragma comment (Lib, "glu32.lib") # pragma comment (Lib, "glu32.lib ") # define left_edge 1 # define right_edge 2 # define bottom_edge 4 # define top_edge 8 Static int times = 1; // draw from (x0, y0) to (x1, Y1) line void linegl (INT x0, int y0, int X1, int Y1) {glbegin (gl_lines); glcolor3f (1.0f, 0.0f, 0.0f); glvertex2f (x0, y0 ); glcolor3f (0.0f, 1.0f, 0.0f); glvertex2f (x1, Y1); glend ();} // Type Def struct rectangle {float xmin; float xmax; float ymin; float Ymax;} rectan; rectan rect; int x0, y0, X1, Y1; // find the Cohen-Sutherland code int compcode (int x, int y, rectan rect) of the coordinate point) {int code = 0x00; If (Y <rect. ymin) {code = Code | 4;} If (Y> rect. ymax) {code = Code | 8;} If (x> rect. xmax) {code = Code | 2;} If (x <rect. xmin) {code = Code | 1;} return code;} // crop a straight line int cohensu Therlandlineclip (rectan rect, Int & x0, Int & y0, Int & X1, Int & Y1) {int accept = 0, done = 0; float X, Y; int code0, code1, codeout; int x00 = x0, y00 = y0, X11 = x1, y11 = Y1; code0 = compcode (x0, y0, rect); code1 = compcode (x1, Y1, rect); // If (! (Code0 | code1) {accept = 1; done = 1;} // the two points of the straight line are on the same side (top, bottom, and right) of the rectangle. Left), should be removed. If (code0 & code1) {done = 1;} while (! Done) {// There is an intersection between a straight line and a rectangle. Only the IF (! (Code0 | code1) {accept = 1; done = 1;} else {If (code0! = 0) {codeout = code0;} else {codeout = code1;} If (codeout & left_edge) {Y = y0 + (y1-y0) * (rect. xmin-x0)/(x1-x0); X = (float) rect. xmin;} else {If (codeout & right_edge) {Y = y0 + (y1-y0) * (rect. xmax-x0)/(x1-x0); X = (float) rect. xmax;} else {If (codeout & bottom_edge) {x = y0 + (x1-x0) * (rect. ymin-y0)/(y1-y0); y = (float) rect. ymin;} else {If (codeout & top_edge) {x = x0 + (x1-x0) * (rect. ymax-y0)/(y1-y0); y = (float) rect. ymax ;}}} if (codeout = Code0) {x0 = x; Y0 = y; code0 = compcode (x0, y0, rect);} else {x1 = x; Y1 = y; code1 = compcode (x1, Y1, rect);} // the line and the rectangle do not intersection, but the two points of the line are on different sides of the rectangle. In this case, remove them. If (Times <= 3) & (code0 & code1) {x0 = x1; Y0 = Y1; done = 1; accept = 1 ;}} if (accept) {linegl (x0, y0, X1, Y1);} return accept;} void mydisplay () {glclear (gl_color_buffer_bit); glcolor3f (1.0f, 0.0f, 0.0f); reglctf (rect. xmin, rect. ymin, rect. xmax, rect. ymax); linegl (x0, y0, X1, Y1); glflush ();} void Init () {glclearcolor (0.0, 0.0, 0.0, 0.0); glshademodel (gl_flat ); rect. xmin = 100; rect. xmax = 300; rect. ymin= 100; rect. ymax = 300; X0 = 0; Y0 = 650; X1 = 650; Y1 = 0;} void reshape (int w, int h) {glviewport (0, 0, (glsizei) W, (glsizei) H); glmatrixmode (gl_projection ); glloadidentity (); gluortho2d (0.0, (gldouble) W, 0.0, (gldouble) H);} // you can specify C for the letter on the keyboard, R for the letter, and X for the letter to exit. Void keyboard (unsigned char key, int X, int y) {Switch (key) {Case 'C': cohensutherlandlineclip (rect, x0, y0, X1, Y1 ); glupostredisplay (); break; Case 'r': Init (); glupostredisplay (); break; Case 'X': exit (0); break; default: break ;}} int main (INT argc, char * argv []) {gluinit (& argc, argv); gluinitdisplaymode (glu_rgb | glu_single); gluinitwindowposition (100,100); gluinitwindowsize (640,480 ); glucreatewindow ("crop"); Init (); gludisplayfunc (mydisplay); glureshapefunc (reshape); glukeyboardfunc (keyboard); glumainloop (); Return 0 ;}
Experiment results (different (x0, y0) and (x1, Y1) can be obtained ):