格斯文档网

您现在的位置是:格斯文档网 > 心得体会 >

直线段剪裁实验报告

 《计算机图形学》实验报告

 《实验名称》

 直线段裁剪 姓名

 学号

  专业

 班级

  天津大学计算机科学与技术学院 一、实验目得 熟练掌握 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ﻩ}

推荐访问:线段 剪裁 实验

版权所有:格斯文档网 2010-2024 未经授权禁止复制或建立镜像[格斯文档网]所有资源完全免费共享

Powered by 格斯文档网 © All Rights Reserved.。浙ICP备19042928号