光 栅 图 形 学 算 法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
光栅图形学-裁剪-Cohen_Sutherland
使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕显示的只是图的一部分,因此需要确定图形中哪些图形显示在显示区之内,哪些落在显示区之外,这样便于只显示落在显示区内的那部分图形,以提高显示效率。
直线段裁剪算法比较简单,但比较重要,是复杂图元裁剪的基础。
裁剪前(矩形为窗口区):
裁剪后:
Cohen_Sutherland裁剪算法:对于每条线段P1,P2,分为三种情况处理。
1、若P1P2完全在窗口内,则显示该线段P1P2,简称取之。
2、若P1P2明显在窗口外,则丢弃该线段,简称弃之。
3、若前段既不满足取的条件,也不满足弃的条件,则在交点处把线段分为两段,其中一段完全在窗口外,可弃之,然后对另一段重复上述处理。
用编码判断一条直线段与窗口属何种关系。
1001|1000|1010
----|----|-----
0001|0000|0010
----|----|-----
0101|0100|0110
裁剪一条线段时,先求出P1P2所在的区号code1,code2,若code1=0,且code2=0,则线段P1P2在窗口内,应取之。
若按位与运算code1code2!=0,则两个端点同在窗口的上方、下方、左方或右方,可判断线段完全在窗口外,可弃之。
否则按第三种情况处理。
求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段在窗口外,可弃之,再对说另一段重复上述处理。
定义的宏:
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
辅助函数:
int CDrawView::encode(int x,int y,int XL,int XR,int YB,int YT) --端点与窗口边界
--获得端点的编码
-*1001|1000|1010
----|----|-----
0001|0000|0010
----|----|-----
0101|0100|0110*-
c|=LEFT;
c|=RIGHT;
c|=BOTTOM;
return c;
实现源码:
void CDrawView::CS_Clip(int x1,int y1,int x2,int y2,int XL,int XR,int YB,int YT)
--Cohen_Sutherland裁剪算法
--对于每条线段p1p2分为3种情况处理:
--若p1p2完全落在窗口内,则显示该线段p1p2,取之(两个编码都为0)
--若p1p2明显在窗外,则丢弃该线段,弃之(code1code2!=0) --若线段不满足取得条件,也不满足弃的条件,则在交点出把先把线段分为两段,其中
--一段完全在窗口外,弃之,对另外一段重复处理
int code,code1,code2,x,y;
code1=encode(x1,y1,XL,XR,YB,YT); --获得编码
code2=encode(x2,y2,XL,XR,YB,YT);
while(code1!=0||code2!=0)
if(code1code2)
if(code1)
code=code1;
code=code2;
if(LEFTcode) --求得与窗口边界的交点
y=y1+(y2-y1)*(x-x1)-(x2-x1);
else if(RIGHTcode)
y=y1+(y2-y1)*(x-x1)-(x2-x1);
else if(BOTTOMcode)
x=x1+(x2-x1)*(y-y1)-(y2-y1);
else if(TOPcode)
x=x1+(x2-x1)*(y-y1)-(y2-y1);
if(code==code1) --更新code值
code1=encode(x1,y1,XL,XR,YB,YT);
code2=encode(x2,y2,XL,XR,YB,YT);
MiddleDrawline(x1,y1,x2,y2,RGB(255,0,0));--绘制在窗口内的线
种子象素入栈;当栈非空时重复执行如下三步操作:
[1] Fundamentals of Computer Graphics 4th
用式(1.2)计算符号时,需要4个加法和2个乘法。
事实上,ddd 是xp,ypx_p,y_pxp?,yp?的线性函数,因此可采用增量计算,提高运算效率。
方法如下
d = 2*A*i + B*(2*j + 1) + 2*C;
通过以上我们可以看出,Bresenham算法并没有去求k,b亦或是A,B,C,仅仅是通过两点坐标去绘制直线,不限定直线方程类型,集合DDA与中点画线法优势,应用更广泛。
渲染一幅三维物体图像所涉及的知识、实际上就是计算机图形中
每个像素看上去应该是什么颜色的问题。
这很大程度上取决于不同的光照模型。
( 3)否则,窗口内含有两个以上的面,则把窗口等分成四个子窗口。
对每个小窗口再做上述同样的处理。
这样反复地进行下去直线段裁剪算法复杂图形裁剪的基础。
?直线段和剪裁窗口的可能关系:
int dy = m_end.m_y - m_start.m_y;
前面介绍了经典的 Z-buffer 算法,思想是开一个和帧缓存一样大小的存储空间,利用空间上的牺牲换取算法上的简介。