直线段剪裁实验报告
《计算机图形学》实验报告
《实验名称》
直线段裁剪 姓名
学号
专业
班级
天津大学计算机科学与技术学院 一、实验目得 熟练掌握 Cohen—Sutherland 直线裁剪算法,并编程实现 二、实验内容 (1)
裁剪窗口为矩形窗口,且矩形边与坐标轴平行,长宽自己定。
(2)
待裁剪线段端点坐标自己定;裁剪线段涵盖完全可见、不完全可见、完全不可见类型。
(3)
要求显示待裁剪线段并用不同颜色标示出裁剪结果。
实现方法:一般情况下,需要判断一条直线就是全部可见,全部不可见,部分裁剪(一段裁剪),全部裁剪(两端裁剪).通过把裁剪区域分成许多部分,然后给每一段被裁剪得线段得两端分配一位代码,通过少量if语句与一个case语句就可以判断出具体情况。
伪代码如下: #define CLIP_CODE_C 0
0000xﻩ#define CLIP_CODE_N 0
8000xﻩ#define CLIP_CODE_S
0x0004 #define CLIP_CODE_E
0x0002 #define CLIP_CODE_W
0x0001 #define CLIP_CODE_NE 0
a000xﻩ#define CLIP_CODE_SE 0
6000xﻩ#define CLIP_CODE_NW 0
9000xﻩ#define CLIP_CODE_SW 0
5000xﻩ 实验步骤:
1)生成裁剪窗口,窗口由直线 xl=250,xr=850,yb=250,yt=450 2)绘制直线段
3)编写 Cohen—Sutherland 直线裁剪算法,对直线段进行裁剪 编码定义规则:
第一位 C1:若端点位于窗口之左侧,即 X<xl,则 C1=1,否则 C1=0。
第二位 C2:若端点位于窗口之右侧,即 X〉xr,则 C2=1,否则 C2=0。
第三位 C3:若端点位于窗口之下侧,即 Y〈yb,则 C3=1,否则 C3=0。
第四位 C4:若端点位于窗口之上侧,即 Y>yt,则 C4=1,否则 C4=0. 裁剪步骤: 对所有直线得端点都建立了区域码之后,就可按区域码判断直线在窗口之内或窗口之外。这可分为如下几种情况:
①若一直线得两个端点得区域码均为0000 则此直线在窗口边界之内,应子保留。
②若一直线得两个端点得区域码得同一位同时为 1,则此直线全部在窗口边界之外,应子裁剪。例如,若一直线得一个端点得区域码为 1001,另一个端点得区域码为 0101,则此两端点得区域码得第一位均为1,说明此两端点均在窗口边界之左,因此,直线在窗口边界之外,应予裁剪。可用将直线两个端点得区域码进行与操作得方法,判断直线就是否在窗口之外,若与操作得结果为0000则两端点得区域码任何位均不同时为1此直线不一定被裁剪。
③以上两种情况之外得直线,有可能穿过窗口,也有可能不穿过窗口,
下图中所示得两条直线都不符合情况②得要求,但一条直线(P1P2)穿过窗口,另一直线(P3P4)不穿过窗口。对这类直线可以进行如下处理:取窗口外得一个端点与窗口边界比较以确定可排除直线得哪一部分,然后,把直线剩下得部分与其她边界比较,这样一直到直线全部被排除或确定直线得哪一部分在窗口之内为止。可按“左、右、下、上”得次序建立检查直线端点与窗口边界关系得算法。
图③ 三、实验结果
画线效果一:
画线效果二:
其她效果用户可自行绘制 四、实验分析与总结 掌握了openGL得基本用法,掌握了Cohen—Sutherland直线裁剪算法,并编程实现出来、 五、源代码 void CCsLineView::Cohen()//Cohen-Sutherland 算法 {
;egnahC LOOBﻩ
;y,x elbuodﻩ RC0=EnCode(Pointx[0],Pointy[0]);
RC1=EnCode(Pointx[1],Pointy[1]);
)EURT(elihwﻩ {
Change=FALSE;
))1CR|0CR( == 0(fiﻩ//{ ﻩ
之取简ﻩ
ﻩ return;
} ﻩ ﻩ
else if(0!=(RC0 & RC1))
//{
之弃简ﻩ
ﻩ return;
} ﻩ ﻩ ﻩ
esleﻩ
{
外口窗在点 0p 证保,1P与0P 换交,内口窗在点 0P 果如//)0CR==0(fiﻩ { ﻩ ﻩ ﻩ
//
值标坐得点换交ﻩ
ﻩ double TPointx,TPointy;
ﻩ
;]0[ytnioP=ytnioPT;]0[xtnioP=xtnioPTﻩ
ﻩ
;]1[ytnioP=]0[ytnioP;]1[xtnioP=]0[xtnioPﻩ
ﻩ
;ytnioPT=]1[ytnioP;xtnioPT=]1[xtnioPﻩ ﻩ ﻩ //
值码编得点换交ﻩ
unsigned int TRC;
ﻩ
;CRT=1CR;1CR=0CR;0CR=CRTﻩ
} ﻩ// ﻩ ﻩ
剪裁序顺得上、下、右、左按ﻩ ﻩ ﻩ
侧左得口窗于位点 0P//) TFEL & 0CR(fiﻩ
ﻩ {
ﻩ ﻩ
y 点交求//;lxw=xﻩ ﻩ ﻩ
nioP(/)]0[xtnioP-x(*)]0[ytnioP—]1[ytnioP(+]0[ytnioP=yﻩtx[1]-Pointx[0]);
;y=]0[ytnioP;x=]0[xtnioPﻩ ﻩ ﻩ ﻩ
;EURT=egnahCﻩ
ﻩ ﻩ
RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);
ﻩ ﻩ} ﻩ
ﻩ
侧右得口窗于位点0P//) THGIR & 0CR(fiﻩ
{
ﻩ ﻩ
y点交求//;rxw=xﻩ
ﻩ
y=Pointy[0]+(Pointy[1]-Pointy[0])*(x—Pointx[0])/(Pointx[1]-Pointx[0]);
ﻩ ﻩ
Pointx[0]=x;Pointy[0]=y;
ﻩ ﻩ
;EURT=egnahCﻩ
ﻩ tnioP,]1[xtnioP(edoCnE=1CR;)]0[ytnioP,]0[xtnioP(edoCnE=0CRﻩy[1]);
ﻩ ﻩ ﻩ} ﻩ ﻩ
侧下得口窗于位点 0P//) MOTTOB & 0CR(fiﻩ { ﻩ ﻩ ﻩ ﻩ ﻩ
x 点交求//;byw=yﻩ
ﻩ x=Pointx[0]+(Pointx[1]—Pointx[0])*(y-Pointy[0])/(Pointy[1]-Pointy[0]);
ﻩ Pointx[0]=x;Pointy[0]=y;
ﻩ
;EURT=egnahCﻩ
ﻩ RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);
} ﻩ ﻩ
ﻩ
ﻩ if(RC0 & TOP )//P0 点位于窗口得上侧
{ ﻩ
x 点交求//;tyw=yﻩ ﻩ ﻩ ﻩ nioP(/)]0[ytnioP—y(*)]0[xtnioP-]1[xtnioP(+]0[xtnioP=xﻩ
ty[1]—Pointy[0]);
;y=]0[ytnioP;x=]0[xtnioPﻩ
ﻩ ﻩ
;EURT=egnahCﻩ
ﻩ oP,]1[xtnioP(edoCnE=1CR;)]0[ytnioP,]0[xtnioP(edoCnE=0CRﻩinty[1]);
ﻩ }
ﻩ if(FALSE==Change)
{ ﻩ ﻩ
ﻩ ﻩ return;
}ﻩ ﻩ
} ﻩ } ﻩ} void CCsLineView::OnDraw(CDC* pDC)
{
CRect Rect;
GetClientRect(&Rect);//获得客户区得大小
CBitmap Bitmap,*pBitmap;
;)1PAMTIB_BDI(pamtiBdaoL、pamtiBﻩ CDC MemDC;
;))(CDteG(CDelbitapetaerC、CDmeMﻩ
;)pamtiB&(tcejbOtceleS、CDmeM=pamtiBpﻩ S,0,0,erutciP&,)(thgieH、tceR,)(htdiW、tceR,0,0(tlBtiB、CDmeMﻩRCCOPY);
题标口窗//;)"口窗",02-byw,2/)rxw+lxw((tuOtxeT、CDmeMﻩ //绘制窗口与直线
CPen Pen3,*pOldPen3;//定义3个像素宽度得画笔
;))0,0,0(BGR,2,DILOS_SP(nePetaerC、3nePﻩ
;)3neP&(tcejbOtceleS、CDmeM=3nePdlOpﻩ MemDC、MoveTo(wxl,wyt);MemDC、LineTo(wxr,wyt);
;)byw,lxw(oTeniL、CDmeM;)byw,rxw(oTeniL、CDmeMﻩ MemDC、LineTo(wxl,wyt);MemDC、SelectObject(pOldPen3);
Pen3、DeleteObject();
CPen Pen1,*pOldPen1;//定义 1 个像素宽度得画笔
Pen1、CreatePen(PS_SOLID,2,RGB(255,0,0));
;)1neP&(tcejbOtceleS、CDmeM=1nePdlOpﻩ if(m_i>=1)
{ ﻩ ﻩ
;))]0[ytnioP(DNUOR,)]0[xtnioP(DNUOR(oTevoM、CDmeMﻩ
ﻩ ;))]1[ytnioP(DNUOR,)]1[xtnioP(DNUOR(oTeniL、CDmeMﻩ ﻩ
} ﻩ MemDC、SelectObject(pOldPen1);
Pen1、DeleteObject(); ﻩ
;)(CDteG=cd* CDCﻩ RS,0,0,CDmeM&,)(thgieH、tceR,)(htdiW、tceR,0,0(tlBtiB〉—cdﻩCCOPY);
;)pamtiBp(tcejbOtceleS、CDmeMﻩ} void CCsLineView::Ondrawline() //屏幕画线函数 {
if(FALSE==m_Attatch)
{ ﻩ ﻩ
;))(CDteG(CDelbitapetaerC、erutciPﻩ
*pamtiBCﻩ
;pamtiBp*,pamtiBﻩ
Bitmap=new CBitmap;
;)1PAMTIB_BDI(pamtiBdaoL>-pamtiBﻩ
;)pamtiB(tcejbOtceleS、erutciP=pamtiBpﻩ
;EURT=hctattA_mﻩ }
m_Draw=TRUE;
;0=i_mﻩ
;)ESLAF(etadilavnIﻩ 示显//;)"法算剪裁线直 dnalrehtuS—nehoC"(txeTwodniWteS〉-)(dnWniaMteGxfAﻩ标题
MessageBox("请使用鼠标在屏幕上绘制直线,然后点击裁剪按钮进行裁剪”,”提示",MB_OKCANCEL); ﻩ} void CCsLineView::OnMouseMove(UINT nFlags, CPoint point)
//鼠标移动函数 {
// TODO: Add your message handler code here and/or call default
if(TRUE==m_Draw)
{ ﻩ
)2<i_m(fiﻩ { ﻩ ﻩ
ﻩ Pointx[m_i]=point、x;Pointy[m_i]=point、y;
ﻩ Invalidate(FALSE);
} ﻩ }
;)tniop ,sgalFn(evoMesuoMnO::weiVCﻩ} void CCsLineView::OnLButtonDown(UINT nFlags, CPoint point) //单击鼠标左键函数 {
ﻩ
)warD_m==EURT(fiﻩ {
)2〈i_m(fiﻩ
{
Pointx[m_i]=point、x;Pointy[m_i]=point、y;
ﻩ ﻩ m_i++;
} ﻩ } ﻩ
;)tniop ,sgalFn(nwoDnottuBLnO::weiVCﻩ}
上一篇:市优秀班集体申报材料样本与市供水公司管网控漏交流材料汇编
下一篇:农场规划方案