




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验一直线与圆的绘制
(一)实验目的
掌握用Besenham法编程实现直线和圆的绘制。会编程绘制虚线、点划线和具
有一定宽度的直线。
(二)实验内容
用实现直线和圆的绘制
基本规定:
(1)数据输入项为:直线的起点与终点坐标,圆心坐标与半径
(2)直线与圆输出在中
附加规定:
(1)通过用户输入可改变直线的线型(实线、虚线与点划线)
(2)通过用户输入可改变直线的线宽(用方刷子解决)
(3)通过用户输入可改变直线和圆的颜色
(三)实验所用仪表及设备
使用实验室提供的PC机。使用VisualC++编程。
(四)实验环节
1.设计思绪
1)设计对话框类
2)设计菜单
3)设计CMydrawView类
数据成员
protected:
doublex0,y0,x1,yl,R;〃直线始点与终点、圆的半
径
intcx,cy;//圆的坐标;
成员函数
voidMybline();//直线中点Bresenham函数
voidCirclePoint(doublex,doubley);/〃l分子画圆子
函数
voidMbcircle();〃圆中点Bresenham函数
4)程序代码
voidCMydrawView::Mybline()//中点Bresenham函数
(
SCCIientDCdc(this);
(3COLORREFrgb=RGB(0,255,0);//定义直线颜色为蓝色
0doubIex,y,d,k,t:
x=x0;y=y0;
0
if(abs(xl-xO)<le-6)
(
if(yl<yO)
(
0t=y0;yO=yl;y1=t;
00)
0for(x=x0,y=y0;y<=y1;y++)
0de.SetPixel(ROUND(x),ROUND(y),rgb);
else
{
0k=(yl-yO)/(xl-x0);d=0.5-k;
if(k>1)
00Sif(y1<y0)
St=yO;y0=y1;yl=t;
S00t=x0;x0=xl;x1=t:
m}
00d=l-0.5*k;
目for(x=xO/y=y0;y<=y1;y++)
00de.SetPixel(ROUND(x),ROUND(y),rgb);
团if(d>=O)
a0{
00X++;
0013d+=1—k;0
00}
13else
0{
0d+=1;
000}
S)
)
raf(0<=k&&k<=l)
喇
醛if(xO>xl)
0{
但00t=xO;x0=x1;xl=t;
团t=yO;y0=y1;yl=t;
TO}
Sd=0.5-k;
03Sfor(x=x0,y=yO;x<xl;x++)
SS(
dc.SetPixelfROUND(x),ROUND(y),rgb);
B0
0if(d<0)
0{
0y++;
国团d+=1—k;
00)
03团else
d-=k;
000)
团)
函if(k>=-l&&k<0)
朗
团团if(x0>xl)
000t=xO;xO=x1;xl=t;
励团t=yO;y0=y1;y1=t;
0)
0d=-O.5-k;
00for(x=x0zy=yO;x<xl;x++)
喇
团团;
dc.SetPixel(ROUND(x),ROUND(y)zrgb)
00(3if(d>0)
00{
团y-;
0d—=l-k;
m)
由else
E0d-=-k;
000}
)
if(k<-l)
明
团if(yO<y1)
000{
团随t=y0;yO=yl;yl=t;
0t=x0;xO=xl;xl=t;
}
000d=-1-0.5—k;
团for(x=x0,y=y0;y>yl;y--)
m(
0dc.SetPixel(ROUND(x),ROUND(y),rgb);
函if(d<0)
0图{
团团x++;
0003d-=l+k;
团)
团00eIse
目函d-=1;
0}
回}
)
)
voidCMydrawView::OnMenuitem32772()〃直线菜单函数
(
//TODO:Addyourcommandhandlercodehere
InputDIgdig;
if(dlg.DoModal()==IDOK)
0{
团x0=dlg.m_x0;
xl=dlg.m_x1;
国y0=d1g.m_y0;
0yl=dlg.m_yl;
0)
AfxGetMainWnd()->SetWindowText("基本图形扫描转换:Mybline");
//RedrawWindow();
0Mybline();
voidCMydrawView::Mbcirc1e()〃圆中点Bresenham函数
(
0doub1ex,y,d;
d=l.25—R;x=0;y=R;
0for(x=O;x<y;x++)
(
但Circ1ePoint(x,y);
团if(d<0)
图d+=2*x+3;
Seise
回{
0d+=2*(x—y)+5;
y-;
}
01
)
voidCMydrawView::CircIePoint(doub1ex,doubley)〃八分子画圆函数
(
CCIientDCdc(this);
COLORREFrgb=RGB(0,0,255);
Sdc.SetPixel(ROUND(x)+cx,ROUND(y)+cy,rgb);
dc.SetPixe1(ROUND(y)+cx,ROUND(x)+cy,rgb);
dc.SetPixel(-ROUND(y)+cxzROUND(x)+cy,rgb);
Sdc.SetPixe1(ROUNDfx)+cx,-ROUND(y)+cy,rgb);
0dc.SetPixel(-ROUND(x)+cxROUND(y)+cy,rgb);
dc.SetPixel(-ROUND(y)+cx,-ROUND(x)+cy,rgb);
dc.SetPixe1(ROUND(y)+cx,—ROUND(x)+cy,rgb);
dc.SetPixe1(—ROUND(x)+cx,ROUND(y)+cyjgb);
)
voidCMydrawView::OnMENUITEMCircle()//圆菜单函数
(
//TODO:Addyourcommandhandlercodehere
circleDIgdig;
0if(dlg.DoModal()==lDOK)
0{
R=dIg.m_r;
0cx=dlg.m_ex;
cy=dlg.m_cy;
)
AfxGetMainWnd()->SetWindowText("基本图形扫描转换:Mbcirc1e");
Mbcircle();
)
voidCMydrawView::OnMENUITEMclear()〃清屏菜单函数
{
//TODO:Addyourcommandhand1ercodehere
SRedrawWindow();
}
5)运营结果
直线:
(五)思考题
如何修改程序使其适合于当直线斜率大于一或小于零时的情况?
答:分组讨论大于一和小于零的情况,分别计算机d的值,程序如下:
if(k>1)
。{oif(yl<yO)
a{<>t=yO;y0=y1;y1=t;
”=xO;xO=xl;x1=t?}
d=1-0.5*k;
。for(x=xO,y=yO;y<=y1;y++)
。(vdc.SetPixel(R0UND(x),ROUND(y),rgb);
。if(d>=0)
{flx++;
。。d+=l-k?®}
gelse
2{d+=1;0Jo)®)
if(k>=-l&&k<0)
。{if(x0>x1)
Ofijot=x0:xO=x1:xl=t;
qt=y0;y0=yl;yl=t;}
gd=-0.5-k:
。ofor(x=x0,y=y0;x<xl;x++)
{«dc.SetPixel(ROUND(x),ROUND(y),rgb);
if(d>0)
。。o(j-=1-k;)
。。else
°°d-=-k;。})
“f(kv-1)
。。{if(y0<yl)
。。{t=y0;y0=yl;yl=t;
。t=x0;x0=xl;xl=t)
。d=-l-0.5-k;
。for(x=x0,y=y0;y>i:y—)
。皿。dc.SetPixel(ROUND(x),ROUND(y),rgb);
。。if(d<0)
。。{x++;
。ad-=l+k;o)
。else
00d-=1;o}。}
实验二图形的裁剪
一、实验目的
掌握用编码法裁剪二维线段及逐边裁剪算法裁剪多边形的编程方法,并实现之。
二、实验内容'
用编码法裁剪二维线段用逐边裁剪算法裁剪多边形
基本规定:(1)数据输入项为:裁剪窗口四条边坐标
对于编码法裁剪二维线段要输入线段的起点与终点x,y坐标。
对于逐边裁剪算法裁剪多边形要输入多边形的顶点数及各顶
点x,y坐标。
(2)裁剪前与裁剪后的结果输出在活动窗口中。
附加规定:对于裁剪多边形可由用户控制裁剪的边逐边裁剪。
三、实验所用仪表及设备
使用实验室提供的PC机。使用VisualC++编程。
四、实验环节
1.编码法裁剪二维线段
己知线段端点的区域码,就可以判断直线与裁剪窗口之间的关系。
1001彳10
0001J
0010
01000110
(1)假如两端点的编码均为0000,直线在窗口内。
(2)假如两端点的编码相与不为0000,表达直线在窗口外。
(3)否则对端点编码,根据从右到左(或从左到右)顺序判别编码位是否为1,拟定与窗
口求交的边界并求出交点,裁剪线段,将交点作为直线的新端点,反复以上(1)(2)环节。
例如上图直线:
a.左端点1的编码0101,右端点2的编码1010o
b.符合(3),计算交点。
c.设从左端点开始,由于1号端点的编码为0101,从左边开始,第一位是1,所以与左
边界有交点,求交点3。
d.计算3号点的编码为0000o
e.3号点与2号点的关系仍符合(3)。
f.由于3号点的编码为0000,已在窗口内,再从右端2号点开始计算交点,由于2号
端点的编码为1010,从左边开始,第二位是1,所以与右边界有交点,求交点4,其编
码为1000。
g.3号点与4号点的关系仍符合(3)。
h.由于4号端点的编码为1000,从左边开始,第四位是1,所以与上边界有交点,求交
点5,其编码为0000。
i.3号点与5号点的关系符合(1),结束。
Cohen-SutherLand裁剪算法伪程序如下:
#defineLEFT1//0001,左
#defineRIGHT2//0010,右
#defineBOTTOM4//0100,下
#defineTOP8//I000,上
//已知端点坐标(x,y),求其所在区的编码odeo
2.设计思绪
a)设计菜单函数
直线菜单函数
裁剪菜单函数
b)设计绘画窗口
装载位图函数
定义画笔绘制窗口
定义画笔绘制直线
c)设计裁剪函数
d)设计端点编码函数
3.程序主代码
//MyCutView.cpp:imp1ementationoftheCMyCutViewclass
//
#include"stdafx.h"
#inc1ude"MyCut.h"
#include"MyCutDoc.h"
#inelude"MyCutView.h"
#defineROUND(a)int(a+0.5)
#ifdef_DEBUG
#definenewDEBUGNEW
#undcfTHIS_FILE
staticcharTHIS_HLE[]=_FILE_;
#endif
#defineLEFT1
#defineRIGHT2
#defineBOTTOM4
#defineTOP8
////////////////////////////////////////////////////III//////////////////////
//CMyCutView
IMPLEMENT.DYNCREATE(CMyCutView,CView)
BEGIN_MESSAGE_MAP(CMyCutView,CView)
//{(AFX_MSG_MAP(CMyCutView)
»ON_COMMAND(ID_MENUITEMdraw1ine,OnMENUITEMdraw1ine)
ON_COMMAND(ID_MENUITEMclip,OnMENUITEMclip)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
。//}}AFX_MSG_MAP
//Standardprintingcommands
ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)
»ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFi1ePrint)
»ON_COMMAND(1D_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////num/muim///////////////////////////////
//CMyCutViewconstruction/destruction
CMyCutView::CMyCutView()
(
//TOD0:addconstructioncodehere
wx1=200;wxr=850;wyb=200;wyt=450;
“n_attatch=FALSE;
m_i=0;
®m_draw=FALSE;
RC0=0;RCl=0;
)
CMyCutView::-CMyCutView()
{
)
OOLCMyCutView::PreCreateWindow(CREATESTRUCT&cs)
(
。//TODO:ModifytheWindowclassorstylesherebymodifying
“/theCREATESTRUCTcs
returnCView::PreCreateWindow(cs);
)
////Illi/〃/〃/〃/〃〃〃/〃/〃///〃/〃〃〃〃〃/〃/〃///////////////////HUH
//CMyCutViewdrawing
voidCMyCutView::OnDraw(CDC*pDC)
(
CMyCutDoc*pDoc=GetDocument();
«ASSERT_VALID(pDoc);
。〃TOD0:adddrawcodefornativedatahere
//装载位图
oCRectRect;
GetC11611证(:1(&1^。0;〃获得客户区的大小
«>CBitmapBitmap,*pBitmap;
^Bitmap.LoadBitmap(IDB_BITMAP1);。
CDCMemDC;
oMemDC.CreateCompatibleDC(GetDC());
叩Bitmap=MemDC.Select0bject(&Bitmap):
MemDC.BitBlt(O,O,Rect.Width(),Rect.Height(),&Picture,0,0,SRCCOPY);。
MemDC.TextOut((wxl+wxr)/2,wyb-20J窗口)〃窗口标题
。//绘制窗口和直线
CPenPen3,*pO1dPen3;//定义3个像素宽度的画笔
®Pen3.CreatePen(PS_SOLID,3,RGB(0,0,0));
pOldPen3=MemDC.Se1ectObject(&Pen3);
®MemDC.MoveTo(wx1,wyt);MemDC.LineTo(wxr,wyt);
McmDC.LineTo(wxr,wyb);McmDC.LincTo(wxl,wyb);
oMemDC.LineTo(wxl,wyt);McmDC.Se1ec10bject(pO1dPen3);
Pen3.DeleteObject();
CPenPenl,*pOIdPenl;〃定义1个像素宽度的画笔
oPenl.CreatePen(PS_SOLID,1,RGB(0,0,255));
pOldPenl=MemDC.SelectObject(&Pen1);
◎if(m_i>=1)
(
emDC.MoveTo(ROUND(Pointx[0]),ROUND(Pointy[0])):
ooMemDC.LineTo(ROUND(Pointx[1]),ROUND(Pointy[l]));。
)
oMemDC.Se1ectObject(pOldPen1);
Pen1.DeleteObject。;。
«CDC*dc=GetDC();
dc->BitBlt(0,0,Rect.Width。,Rect.Height(),&MemDC,0,0,SRCCOPY);
oMemDC.Selec(Object(pBitmap);
}
//////////////////////////////////////////////////〃/////〃/〃/〃/〃〃/////〃
//CMyCutViewprinting
BOOLCMyCutView::OnPreparePrinting(CPrintinfo*pInfo)
<>//defaultpreparation
rctumDoPreparePrinting(plnfo);
)
voidCMyCutView::OnBeginPrinting(CDC*/*pDC*/,CPrintlnfo*/*plnfo*/)
{
//TODO:addextrainitializationbeforeprinting
)
voidCMyCutView::OnEndPrinting(CDC*/*pDC*/,CPrintlnfo*/*plnfo*/)
{
//TODO:addcleanupafterprinting
)
///////////////III///////////////////////////Hllllllllllllllllllllll////////
//CMyCutViewdiagnostics
#ifdef_DEBUG
voidCMyCutView::AssertValid()const
(
»CView::AssertValid();
)
voidCMyCutView::Dump(CDumpContext&de)const
®CView::Dump(dc);
)
CMyCutDoc*CMyCutView::GetDocumcnt()//non-dcbugversionisin1ine
(
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyCutDoc)));
«return(CMyCutDoc*)m_pDocument;
)
#endif//.DEBUG
111/1//〃/〃/〃〃//////////////IIHU//////////////////////////////〃////////
//CMyCutViewmessagehandlers
voidCMyCutView::OnMENUITEMdrawline()
(
//TODO:Addyourcommandhand1ercodehere
if(FALSE==m_attatch)
(
^Picture,CreateCompatib1eDC(GetDC());
oCBitmap*Bitmap,*pBitmap;
aBitmap=newCBitmap;
。//Bitmap—>LoadBitmap(IDB_BITMAPl);
8PBitmap=Picture.SelectObject(Bitinap);
®m_attatch=TRUE;
)
m_draw=TRUE;
®m_i=0;
olnvalidate(FALSE);
◎AfxGetMainWnd()->SetWindowText(MCohen-Sutherland直线裁剪算法");〃显示标题
oMessageBox("请使用鼠标在屏幕上绘制直线,然后点击裁剪按钮进行裁剪“,“提醒”,MB_OKCANC
EL);
。}
voidCMyCutView::OnMENUITEMclip()//裁剪菜单函数
(
。〃TODO:Addyourcommandhandlercodehere
Cut();
Inva1idate(FALSE);
I
voidCMyCutView::OnLButtonDown(UINTnFlags,CPointpoint)
(
“/TOD0:Addyourmessagehand1ercodehereand/orca1Idefau1t
0
Af(TRUE==m_draw)
if(m_i<2)
Pointx[m_i]=point.x;Pointy[m_i]=point.y;
。,m_i++;
°}
)
«CView::OnLButtonDown(nF1ags,point);
)
voidCMyCutView::OnMouseMove(UINTnFlags,CPointpoint)
{
//TODO:Addyourmessagehandlercodehereand/orca11default
if(TRUE==m_draw)
。if(m_i<2)
{
。Pointx[m_i]=point.x;Pointy[m_i]=point.y;
oginva1idate(FALSE);
力
)
^CView::OnMouseMove(nFlags,point);
voidCMyCutView::Cut()
BOOLChange;
«doub1ex,y;
oRC0=EnCode(Pointx[0],Pointy[0]);
RC1=EnCode(Pointx[l],Pointy[1]);
while(TRUE)
。{
。Change=FALSE;
if(0==(RCO|RC1))
。{〃简取之
areturn;
00j
-elseif(0!=(RC0&RC1))
{〃简弃之
return;
)
eIse
if(O==RC0)//假如PO点在窗口内,互换PO和Pl,保证pO点在窗口外
〃互换点的坐标值
。doubleTPointx,TPointy;
®TPointx=Pointx[0];TPointy=Pointy[0];
。oPointx[0]=Pointx[l];Pointy[0]=Pointy[1];
wPointx[l]=TPointx:Pointy[l]=TPointy;
。。。//互换点的编码值
。unsignedintTRC;
。TRC=RC0;RCO=RC1;RC1=TRC;
O0)
。〃按左、右、下、上的顺序裁剪
gif(RC0&LEFT)〃P0点位于窗口的左侧
0»(
8x=wx1;〃求交点y
。y=Pointy[O]+(Pointy[l]-Pointy[0])*(x-Pointx[0])/(Pointx[1]-Pointx[0]);
。ePointx[0]=x;Pointy[O]=y;
。Change=TRUE;
«ORC0=EnCode(Pointx[0],Pointy[0]);RCl=EnCode(Pointx[1],Pointy[1]);
0}g
-if(RC0&RIGHT)//PO点位于窗口的右侧
ggx=wxr;〃求交点y
。。y=Pointy[0]+(Pointy[1]-Pointy[0])*(x-Pointx[0])/(Pointx[l]-Pointx[0]);
ePointx[0]=x;Pointy[0]=y;
。。Change=TRUE;
oRC0=EnCode(Pointx[0],Pointy[01);RC1=EnCode(Pointx[1],Pointy[1]);
j8
。oif(RCO&BOTTOM)〃P0点位于窗口的下侧
0(
8oy=wyb:〃求交点
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 村里拦水坝施工方案
- 增设污水管施工方案
- 智能网联汽车技术 习题及答案 任务2.1 超声波雷达的认知与安装
- 道路垫层施工方案
- 展示设备施工方案范本
- 课题开题报告:基于“组团式”教育援疆背景下的师资队伍建设探索与研究
- 少儿口才训练营:开启语言魅力之旅
- 课题开题报告:积极老龄观视角下的老年人学习意愿影响因素及学习效果研究
- 课题开题报告:湖北省职业教育服务“精准扶贫”的研究与实践
- 2025年数字保密电话机项目合作计划书
- 第16课数据管理与编码(教案)四年级全一册信息技术人教版
- 特殊作业安全管理监护人专项培训课件
- 《节水评价技术导则》
- 课件:《中华民族共同体概论》第一讲 中华民族共同体基础理论
- 2024年贵州省贵阳市中考生物试题(含答案逐题解析)
- 中考英语不规则动词变化表
- 中医师承跟师笔记60篇(共1页)
- BM 带小叶片的高压比压气机叶轮设计BladeGen实例
- 输变电工程建设管理程序指南
- 运营管理部绩效考核表
- 国内外材料牌号对照表非常有用
评论
0/150
提交评论