该算法又称编码算法,裁剪窗口的四条边所在的直线可以把平面分为9个区域,对各个区域的编码包括四位也就是内0外1(比如x坐标小于left记为1,其它记为0),裁剪窗口所在的区域为0000,对于直线段上的端点进行编码,等于该端点所在的区域的编码。编码后就容易判断两个端点的情况,比如求与不等于0,该线段在裁剪窗口之外。
具体算法代码如下:
typedef struct {
unsigned int all;
unsigned left, top, right, bottom;
} OutCode;
void CompOutCode(float x, float y, RECT *rect, OutCode *outCode)
{
outCode->all = 0;
outCode->left = outCode->top = outCode->right = outCode->bottom = 0;
if (x < rect->left)
{
outCode->left = 1;
outCode->all += 1;
}
if (y < rect->top)
{
outCode->top = 1;
outCode->all += 2;
}
if (x > rect->right)
{
outCode->right = 1;
outCode->all += 4;
}
if (y > rect->bottom)
{
outCode->bottom = 1;
outCode->all += 8;
}
}
void CohenSutherlandLineClip(HDC hdc, float x0, float y0, float x1, float y1, RECT *rect)
{
bool accept, done;
OutCode outCode0, outCode1;
float x, y;
accept = false;
done = false;
CompOutCode(x0, y0, rect, &outCode0);
CompOutCode(x1, y1, rect, &outCode1);
do {
if (outCode0.all == 0 && outCode1.all == 0)
{
accept = true;
done = true;
}
else if ((outCode0.all & outCode1.all) != 0)
{
done = true;
}
else
{
OutCode *outCodeOut;
if (outCode0.all != 0)
outCodeOut = &outCode0;
else
outCodeOut = &outCode1;
if (outCodeOut->left)
{
x = rect->left;
y = y0+(y1-y0)*(rect->left-x0)/(x1-x0);
}
else if (outCodeOut->top)
{
x = x0+(x1-x0)*(rect->top-y0)/(y1-y0);
y = rect->top;
}
else if (outCodeOut->right)
{
x = rect->right;
y = y0+(y1-y0)*(rect->right-x0)/(x1-x0);
}
else if (outCodeOut->bottom)
{
x = x0+(x1-x0)*(rect->bottom-y0)/(y1-y0);
y = rect->bottom;
}
if (outCodeOut == &outCode0)
{
x0 = x;
y0 = y;
CompOutCode(x0, y0, rect, &outCode0);
}
else
{
x1 = x;
y1 = y;
CompOutCode(x1, y1, rect, &outCode1);
}
}
} while (!done);
if (accept)
{
MoveToEx(hdc, (int)(x0+0.5f), (int)(y0+0.5f), NULL);
LineTo(hdc, (int)(x1+0.5f), (int)(y1+0.5f));
}
}
该代码基于《计算机图形学》书里的代码修改而成,原书中的代码存在一些问题。
完整的代码可以从这里下载:http://download.csdn.net/detail/qiuchangyong/9763109