將平面分為 9 區域,以 4-bit 編碼表示端點位置(左/右/下/上)。依據編碼快速判斷線段完全內部/外部/需裁剪,再透過參數方程求交點迭代裁剪。
#include <stdio.h>
#include <graphics.h>
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
#define FALSE 0
#define TRUE 1
int get_code(float x, float y,
float xmin, float ymin, float xmax, float ymax) {
int code = 0;
if (y > ymax) code |= TOP;
else if (y < ymin) code |= BOTTOM;
if (x > xmax) code |= RIGHT;
else if (x < xmin) code |= LEFT;
return code;
}
void Line_Clipping(float x1, float y1, float x2, float y2,
float xmin, float ymin, float xmax, float ymax) {
int draw = FALSE, done = FALSE;
int code1 = get_code(x1, y1, xmin, ymin, xmax, ymax);
int code2 = get_code(x2, y2, xmin, ymin, xmax, ymax);
float x, y;
int code;
while (!done) {
if ((code1 | code2) == 0) { draw = TRUE; done = TRUE; }
else if (code1 & code2) { done = TRUE; }
else {
code = code1 ? code1 : code2;
if (code & TOP) {
y = ymax;
x = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
} else if (code & BOTTOM) {
y = ymin;
x = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
} else if (code & RIGHT) {
x = xmax;
y = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
} else if (code & LEFT) {
x = xmin;
y = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
}
if (code == code1) {
x1 = x; y1 = y;
code1 = get_code(x1, y1, xmin, ymin, xmax, ymax);
} else {
x2 = x; y2 = y;
code2 = get_code(x2, y2, xmin, ymin, xmax, ymax);
}
}
}
if (draw) { setcolor(8); line((int)x1, (int)y1, (int)x2, (int)y2); }
}
int main(void) {
float x1=76, y1=40, x2=60, y2=80;
float xmin=50, xmax=80, ymin=50, ymax=70;
int gdriver = DETECT, gmode;
initgraph(&gdriver, &gmode, "C:\\TURBOC2");
setcolor(5);
line((int)x1, (int)y1, (int)x2, (int)y2);
rectangle((int)xmin, (int)ymin, (int)xmax, (int)ymax);
getch();
cleardevice();
setcolor(8);
rectangle((int)xmin, (int)ymin, (int)xmax, (int)ymax);
Line_Clipping(x1, y1, x2, y2, xmin, ymin, xmax, ymax);
getch();
closegraph();
return 0;
}
(code1|code2)==0 全內;code1&code2 全外。