Cohen-Sutherland 算法(编码算法)——计算机图形学笔记 ...
思路将每条直线段分三种情况处理:
[*]完全可见
[*]不完全可见
[*]完全不可见
具体流程
1.求出两端点的编码值
2.进行“与”、“或”运算
[*]若“或”运算后为0,则说明该线段完全可见,取该线段
[*]若“与”运算后不为0,则说明该线段完全不为0,弃该线段
[*]若上述两条件均不成立,则说明该线段不完全可见,按左右下上的顺序用窗各边界裁剪直线段,求出直线段与窗口边界的交点,将完全在窗口外的线段删除
代码
1.初始化
struct point
{
float x;
float y;
float z = 0;
float ratio;
struct message color;
};
double x_left,x_right,y_top,y_bottom;//定义窗口左右上下边界
2.求编码代码
unsigned int enCode(double x, double y)
{
//用1 2 4 8 编码裁剪框的左、右、下、上区域
unsigned int code = 0;
if (x < x_left)
{
code = code | 1;
}
else if (x > x_right)
{
code = code | 2;
}
if (y < y_bottom)
{
code = code | 4;
}
else if (y > y_top)
{
code = code | 8;
}
return code;
}3.裁剪
void cilpping(point point1,point point2)
{
point p1 = point1;//用p1、p2储存直线两个端点
point p2 = point2;
float x; //储存变化后的x,y坐标
float y;
int code1 = enCode(p1.x, p1.y); //code1、code2记录顶点的编码
int code2 = enCode(p2.x, p2.y);
int code = 0;
while (code1 != 0 || code2 != 0) //两直线至少有一点在区域外
{
if ((code1 & code2) != 0)//线段完全不可见,跳出循环
{
return;
}
//将在区域外的点编码给code
code = code1;
if (code1 == 0) \\端点p1在窗口内
code = code2;
if ((1 & code) != 0) //直线段与左边界相交
{
x = x_left;
y = p1.y + (p2.y - p1.y) / (p2.x - p1.x)* (x_left - p1.x);
}
else if ((2 & code) != 0) //直线段与右边界相交
{
x = x_right;
y = p1.y + (p2.y -p1.y)/ (p2.x - p1.x) * (x_right - p1.x);
}
else if ((4 & code) != 0) //直线段与下边界相交
{
y = y_bootom;
x = p1.x + (p2.x - p1.x)/ (p2.x - p1.x) * (y_bottom - p1.y) ;
}
else if ((8 & code) != 0) //直线段与上边界相交
{
y = y_top;
x = p1.x + (p2.x - p1.x)/ (p2.x - p1.x) * (y_top - p1.y);
}
//将求出的点重新赋值
if (code == code1)
{
point1.x = x;
point1.y = y;
code1 = enCode(x, y);
}
else
{
point2.x = x;
point2.y = y;
code2 = enCode(x, y);
}
}
}
页:
[1]