什么是直线段裁剪:
在二维观察中,需要对窗口进行裁剪,即只保留窗口内的图形,去掉窗口外的图形。直线段裁剪即判断直线在窗口内的部分,去除在窗口外的部分(红圈处)。
直线段裁剪算法——Cohen-Sutherland算法:
其基本思想为编码,即对于直线上任一点(x,y),根据其坐标所在的区域,赋予一个4位的二进制码D3D2D1D0。
编码规则如下:
(1)若x<wxl,D0=1,否则D0=0;
(2)若x>wxr,D1=1,否则D1=0;
(3)若y<wyb,D2=1,否则D2=0;
(4)若y>wyt,D3=1,否则D3=0。
举例:假如wxl=1,wxr=3,wyt=2,wyb=1。则点(4,3)的编码就是1010。
由此:直线的两个端点的编码表示出了线段的方位。
算法流程:
① 求出直线段两个端点的编码code1和code2。
② 若code1|code2=0,直线完全在窗口内;若code1&code2≠0,直线则完全在窗口外。
③ 不满足②中的两种情况,此时直线既有在窗口内的部分也有在窗口外的部分。取一个窗口外的端点(编码不为0000)为p。
④ 根据p的编码从低位开始找编码值为1的地方,确定要求交的窗口边界,求出直线段与相应窗口边界的交点,用交点代替p。
⑤ 重复上述过程,直到找不到位于窗口外的点,算法结束。文章来源:https://www.toymoban.com/news/detail-465126.html
代码实现:
p1,p2为直线段两端点,剩余四个参数则对应窗口的四条边。文章来源地址https://www.toymoban.com/news/detail-465126.html
void Cohen-Sutherland(CPoint p1, CPoint p2, int x_min, int y_min, int x_max, int y_max)
{
while (true)
{
//处理两端点的编码
int code0 = 0;
int code1 = 0;
if (p1.x < x_min) code0 += 1;
else if (p1.x > x_max) code0 += 2;
if (p1.y < y_min) code0 += 4;
else if (p1.y > y_max) code0 += 8;
if (p2.x < x_min) code1 += 1;
else if (p2.x > x_max) code1 += 2;
if (p2.y < y_min) code1 += 4;
else if (p2.y > y_max) code1 += 8;
if ((code0 | code1) == 0)
{
cutLine(p1, p2); //对直线段简取之,直线段完全在窗口内
break;
}
else if ((code0 & code1) != 0)
{
break; //直线段完全在窗口外,不进行裁剪,无操作
}
else
{
if (code0 == 0) //点在窗口内,交换两点以取另一个点
{
CPoint pt;
pt = p1;
p1 = p2;
p2 = pt;
int codet;
codet = code0;
code0 = code1;
code1 = codet;
}
if (code0 & 1)
{
p1.y = int(p1.y + ((x_min - p1.x) * (p1.y - p2.y) / (p1.x - p2.x)) + 0.5);
p1.x = x_min;
}
if (code0 & 2)
{
p1.y = int(p1.y + ((x_max - p1.x) * (p1.y - p2.y) / (p1.x - p2.x)) + 0.5);
p1.x = x_max;
}
if (code0 & 4)
{
p1.x = int(p1.x + ((y_min - p1.y) * (p1.x - p2.x) / (p1.y - p2.y)) + 0.5);
p1.y = y_min;
}
if (code0 & 8)
{
p1.x = int(p1.x + ((y_max - p1.y) * (p1.x - p2.x) / (p1.y - p2.y)) + 0.5);
p1.y = y_max;
}
}
}
}
到了这里,关于计算机图形学:直线段裁剪,Cohen-Sutherland算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!