图形学三个最基础的直线裁剪算法
//根据x、y来编码
int EnCode(int x,int y){
int c = 0;
if (x<XL)
{
c |= LEFT;
}
if (x>XR)
{
c |= RIGHT;
}
if (y>YT)
{
c |= TOP;
}
if (y<YB)
{
c |= BOTTOM;
}
return c;
}
//Cohen-Sutherland裁剪算法
void CS_LineClip(int idex,int XL,int YB,int XR,int YT) {
int x1 = gdLDArr[idex].x0;
int x2 = gdLDArr[idex].x1;
int y1 = gdLDArr[idex].y0;
int y2 = gdLDArr[idex].y1;
int code1,code2,code,x,y;
code1 = EnCode(x1,y1);
code2 = EnCode(x2,y2);
while (code1!=0||code2!=0)
{
if ((code1&code2) != 0) {
gdLDArr[idex].x0 = 0;
gdLDArr[idex].y0 = 0;
gdLDArr[idex].x1 = 0;
gdLDArr[idex].y1 = 0;
return;
}
if (code1 != 0) { code = code1; x = x1; y = y1; }
else { code = code2; x = x2; y = y2;}
if ((LEFT&code)!=0)
{
x = XL;
y = y1 + (y2 - y1)*(XL - x1) / (x2 - x1);
}
else if ((RIGHT&code)!=0)
{
x = XR;
y = y1 + (y2 - y1)*(XR - x1) / (x2 - x1);
}
else if ((BOTTOM&code) != 0)
{
y = YB;
x = x1 + (x2 - x1)*(YB - y1) / (y2 - y1);
}
else if ((TOP&code) != 0)
{
y = YT;
x = x1 + (x2 - x1)*(YT - y1) / (y2 - y1);
}
if (code==code1)
{
x1 = x; y1 = y; code1 = EnCode(x, y);
}
else
{
x2 = x; y2 = y; code2 = EnCode(x, y);
}
}
gdLDArr[idex].x0 = x1;
gdLDArr[idex].x1 = x2;
gdLDArr[idex].y0 = y1;
gdLDArr[idex].y1 = y2;
}
//中点裁剪算法
void MP_LineClip(int idex, int XL, int YB, int XR, int YT) {
int x1 = gdLDArr[idex].x0;
int x2 = gdLDArr[idex].x1;
int y1 = gdLDArr[idex].y0;
int y2 = gdLDArr[idex].y1;
int code1, code2, code,xm, ym,xl,xr,yl,yr;
code1 = EnCode(x1, y1);
code2 = EnCode(x2, y2);
while (code1 != 0 || code2 != 0)
{
if ((code1&code2) != 0) {
gdLDArr[idex].x0 = 0;
gdLDArr[idex].y0 = 0;
gdLDArr[idex].x1 = 0;
gdLDArr[idex].y1 = 0;
return;
}
if (code1 != 0) { code = code1;}
else { code = code2;}
if ((LEFT&code) != 0)
{
xl = x1 < x2 ? x1 : x2;
xr = x1 < x2 ? x2 : x1;
yl = xl == x1 ? y1 : y2;
yr = xl == x1 ? y2 : y1;
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
while (xm!=XL)
{
if (xm<XL)
{
xl = xm;
yl = ym;
}
else
{
xr = xm;
yr = ym;
}
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
}
}
else if ((RIGHT&code) != 0)
{
xl = x1 < x2 ? x1 : x2;
xr = x1 < x2 ? x2 : x1;
yl = xl == x1 ? y1 : y2;
yr = xl == x1 ? y2 : y1;
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
while (xm != XR)
{
if (xm<XR)
{
xl = xm;
yl = ym;
}
else
{
xr = xm;
yr = ym;
}
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
}
}
else if ((BOTTOM&code) != 0)
{
yl = y1 < y2 ? y1 : y2;
yr = y1 < y2 ? y2 : y1;
xl = yl == y1 ? x1 : x2;
xr = yl == y1 ? x2 : x1;
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
while (ym != YB)
{
if (ym<YB)
{
yl = ym;
xl = xm;
}
else
{
yr = ym;
xr = xm;
}
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
}
}
else if ((TOP&code) != 0)
{
yl = y1 < y2 ? y1 : y2;
yr = y1 < y2 ? y2 : y1;
xl = yl == y1 ? x1 : x2;
xr = yl == y1 ? x2 : x1;
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
while (ym != YT)
{
if (ym<YT)
{
yl = ym;
xl = xm;
}
else
{
yr = ym;
xr = xm;
}
xm = (xl + xr) / 2;
ym = (yl + yr) / 2;
}
}
if (code == code1)
{
x1 = xm; y1 = ym; code1 = EnCode(x1, y1);
}
else
{
x2 = xm; y2 = ym; code2 = EnCode(x2, y2);
}
}
gdLDArr[idex].x0 = x1;
gdLDArr[idex].x1 = x2;
gdLDArr[idex].y0 = y1;
gdLDArr[idex].y1 = y2;
}
bool ClipT(float p, float q, float *u1, float *u2) {
float r;
if (p<0)
{
r = q / p;
if (r>*u2)
{
return false;
}
if (r > *u1) {
*u1 = r;
}
}
else if (q>0)
{
r = q / p;
if (r<*u1)
{
return false;
}
if (r<*u2)
{
*u2 = r;
}
}
else {
return (q >= 0);
}
return true;
}
//Liang-Barskey裁剪算法
void LB_LineClip(int idex, int XL, int YB, int XR, int YT) {
int x1, x2, y1, y2;
x1 = gdLDArr[idex].x0;
x2 = gdLDArr[idex].x1;
y1 = gdLDArr[idex].y0;
y2 = gdLDArr[idex].y1;
float dx, dy, u1, u2;
u1 = 0;
u2 = 1;
dx = x2 - x1;
dy = y2 - y1;
if (ClipT(-dx,x1-XL,&u1,&u2))
if (ClipT(dx, XR - x1, &u1, &u2))
if (ClipT(-dy, y1 - YB, &u1, &u2))
if (ClipT(dy, YT - y1, &u1, &u2)) {
gdLDArr[idex].x0 = x1 + u1 * dx;
gdLDArr[idex].y0 = y1 + u1 * dy;
gdLDArr[idex].x1 = x1 + u2 * dx;
gdLDArr[idex].y1 = y1 + u2 * dy;
return;
}
gdLDArr[idex].x0 = 0;
gdLDArr[idex].y0 = 0;
gdLDArr[idex].x1 = 0;
gdLDArr[idex].y1 = 0;
}