计算机图形学常用算法实现7 Cohen-Sutherland裁剪算法
在winform下运行
算法本身的实现不算很难,但是这个算法的思路很秀,反正我是想不出来。
代码中的区域为(200,200)~(400,400)的区域
int encode(Point p)
{
int code = 0;
if (p.Y > 400)
code += 8;
if (p.Y < 200)
code += 4;
if (p.X > 400)
code += 2;
if (p.X < 200)
code += 1;
return code;
}
void lineClip(Point p1,Point p2)
{
Graphics g = this.CreateGraphics();
Pen p = new Pen(Brushes.Black);
int code1 = encode(p1);
int code2 = encode(p2);
while (code1 != 0 || code2 != 0)
{
//在直线之外,直接舍去,但是跨过三个区域的情况舍弃不了,需要在后面分割一次再分别舍去
if ((code1 & code2) != 0)
return;
//处理大于上界的点
if ((code1 & 8) != 0)
{
p1.X -= (p1.Y - 400) * (p1.X - p2.X) / (p1.Y - p2.Y);
p1.Y = 400;
code1 = encode(p1);
}
else if ((code2 & 8) != 0)
{
p2.X -= (p2.Y - 400) * (p2.X - p1.X) / (p2.Y - p1.Y);
p2.Y = 400;
code2 = encode(p2);
}
//处理小于下界的点
else if ((code1 & 4) != 0)
{
p1.X -= (p1.Y - 200) * (p1.X - p2.X) / (p1.Y - p2.Y);
p1.Y = 200;
code1 = encode(p1);
}
else if ((code2 & 4) != 0)
{
p2.X -= (p2.Y - 200) * (p2.X - p1.X) / (p2.Y - p1.Y);
p2.Y = 200;
code2 = encode(p2);
}
//处理大于右界的点
else if ((code1 & 2) != 0)
{
p1.Y -= (p1.X - 400) * (p1.Y - p2.Y) / (p1.X - p2.X);
p1.X = 400;
code1 = encode(p1);
}
else if ((code2 & 2) != 0)
{
p2.Y -= (p2.X - 400) * (p2.Y - p1.Y) / (p2.X - p1.X);
p2.X = 400;
code2 = encode(p2);
}
//处理小于左边界的点
else if ((code1 & 1) != 0)
{
p1.Y -= (p1.X - 200) * (p1.Y - p2.Y) / (p1.X - p2.X);
p1.X = 200;
code1 = encode(p1);
}
else if ((code2 & 1) != 0)
{
p2.Y -= (p2.X - 200) * (p2.Y - p1.Y) / (p2.X - p1.X);
p2.X = 200;
code2 = encode(p2);
}
}
g.DrawLine(p, p1, p2);
}