计算机图形学实验报告.docx
- 文档编号:28497135
- 上传时间:2023-07-15
- 格式:DOCX
- 页数:23
- 大小:244.67KB
计算机图形学实验报告.docx
《计算机图形学实验报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告.docx(23页珍藏版)》请在冰豆网上搜索。
计算机图形学实验报告
实验一直线与圆的绘制
(一)实验目的
掌握用Besenham法编程实现直线和圆的绘制。
会编程绘制虚线、点划线和具有一定宽度的直线。
(二)实验内容
用实现直线和圆的绘制
基本要求:
<1)数据输入项为:
直线的起点与终点坐标,圆心坐标与半径
<2)直线与圆输出在中
附加要求:
<1)通过用户输入可改变直线的线型<实线、虚线与点划线)
<2)通过用户输入可改变直线的线宽<用方刷子处理)
<3)通过用户输入可改变直线和圆的颜色
(三)实验所用仪表及设备
使用实验室提供的PC机。
使用VisualC++编程。
(四)实验步骤
1.设计思路
1)设计对话框类
2)设计菜单
3)设计CMydrawView类
数据成员
protected:
doublex0,y0,x1,y1,R。
//直线始点与终点、圆的半径
intcx,cy。
//圆的坐标;
成员函数
voidMybline(>。
//直线中点Bresenham函数
voidCirclePoint(doublex,doubley>。
//八分子画圆子函数
voidMbcircle(>。
//圆中点Bresenham函数
4)程序代码
voidCMydrawView:
:
Mybline(>//中点Bresenham函数b5E2RGbCAP
{
CClientDCdc(this>。
COLORREFrgb=RGB(0,255,0>。
//定义直线颜色为蓝色
doublex,y,d,k,t。
x=x0。
y=y0。
if(abs(x1-x0><1e-6>
{
if(y1
{
t=y0。
y0=y1。
y1=t。
}
for(x=x0,y=y0。
y<=y1。
y++>
dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。
}
else
{
k=(y1-y0>/(x1-x0>。
d=0.5-k。
if(k>1>
{
if(y1
{
t=y0。
y0=y1。
y1=t。
t=x0。
x0=x1。
x1=t。
}
d=1-0.5*k。
for(x=x0,y=y0。
y<=y1。
y++>
{
dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。
if(d>=0>
{
x++。
d+=1-k。
}
else
{
d+=1。
}
}
}
if(0<=k&&k<=1>
{
if(x0>x1>
{
t=x0。
x0=x1。
x1=t。
t=y0。
y0=y1。
y1=t。
}
d=0.5-k。
for(x=x0,y=y0。
x x++> { dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d<0> { y++。 d+=1-k。 } else d-=k。 } } if(k>=-1&&k<0> { if(x0>x1> { t=x0。 x0=x1。 x1=t。 t=y0。 y0=y1。 y1=t。 } d=-0.5-k。 for(x=x0,y=y0。 x x++> { dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d>0> { y--。 d-=1-k。 } else d-=-k。 } } if(k<-1> { if(y0 { t=y0。 y0=y1。 y1=t。 t=x0。 x0=x1。 x1=t。 } d=-1-0.5-k。 for(x=x0,y=y0。 y>y1。 y--> { dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d<0> { x++。 d-=1+k。 } else d-=1。 } } } } voidCMydrawView: : OnMenuitem32772(>//直线菜单函数 { //TODO: Addyourcommandhandlercodehere InputDlgdlg。 if(dlg.DoModal(>==IDOK> { x0=dlg.m_x0。 x1=dlg.m_x1。 y0=dlg.m_y0。 y1=dlg.m_y1。 } AfxGetMainWnd(>->SetWindowText("基本图形扫描转换: Mybline">。 p1EanqFDPw //RedrawWindow(>。 Mybline(>。 } voidCMydrawView: : Mbcircle(>//圆中点Bresenham函数DXDiTa9E3d { doublex,y,d。 d=1.25-R。 x=0。 y=R。 for(x=0。 x x++> { CirclePoint(x,y>。 if(d<0> d+=2*x+3。 else { d+=2*(x-y>+5。 y--。 } } } voidCMydrawView: : CirclePoint(doublex,doubley>//八分子画圆函数RTCrpUDGiT { CClientDCdc(this>。 COLORREFrgb=RGB(0,0,255>。 dc.SetPixel(ROUND(x>+cx,ROUND(y>+cy,rgb>。 dc.SetPixel(ROUND(y>+cx,ROUND(x>+cy,rgb>。 dc.SetPixel(-ROUND(y>+cx,ROUND(x>+cy,rgb>。 dc.SetPixel(ROUND(x>+cx,-ROUND(y>+cy,rgb>。 dc.SetPixel(-ROUND(x>+cx,-ROUND(y>+cy,rgb>。 dc.SetPixel(-ROUND(y>+cx,-ROUND(x>+cy,rgb>。 dc.SetPixel(ROUND(y>+cx,-ROUND(x>+cy,rgb>。 dc.SetPixel(-ROUND(x>+cx,ROUND(y>+cy,rgb>。 } voidCMydrawView: : OnMENUITEMCircle(>//圆菜单函数 { //TODO: Addyourcommandhandlercodehere circleDlgdlg。 if(dlg.DoModal(>==IDOK> { R=dlg.m_r。 cx=dlg.m_cx。 cy=dlg.m_cy。 } AfxGetMainWnd(>->SetWindowText("基本图形扫描转换: Mbcircle">。 5PCzVD7HxA Mbcircle(>。 } voidCMydrawView: : OnMENUITEMclear(>//清屏菜单函数 { //TODO: Addyourcommandhandlercodehere RedrawWindow(>。 } 5)运行结果 直线: (五)思考题 如何修改程序使其适合于当直线斜率大于一或小于零时的情况? 答: 分组讨论大于一和小于零的情况,分别计算机d的值,程序如下: if(k>1> {if(y1 {t=y0。 y0=y1。 y1=t。 t=x0。 x0=x1。 x1=t。 } d=1-0.5*k。 for(x=x0,y=y0。 y<=y1。 y++> {vdc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d>=0> {x++。 d+=1-k。 } else {d+=1。 }}} if(k>=-1&&k<0> {if(x0>x1> {t=x0。 x0=x1。 x1=t。 t=y0。 y0=y1。 y1=t。 } d=-0.5-k。 for(x=x0,y=y0。 x x++> {dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d>0> {y--。 d-=1-k。 } else d-=-k。 }} if(k<-1> {if(y0 {t=y0。 y0=y1。 y1=t。 t=x0。 x0=x1。 x1=t。 } d=-1-0.5-k。 for(x=x0,y=y0。 y>y1。 y--> {dc.SetPixel(ROUND(x>,ROUND(y>,rgb>。 if(d<0> {x++。 d-=1+k。 } else d-=1。 }} 图形的裁剪 一、实验目的 掌握用编码法裁剪二维线段及逐边裁剪算法裁剪多边形的编程方法,并实现之。 二、实验内容` 用编码法裁剪二维线段用逐边裁剪算法裁剪多边形 基本要求: <1)数据输入项为: 裁剪窗口四条边坐标 对于编码法裁剪二维线段要输入线段的起点与终点x,y坐标。 对于逐边裁剪算法裁剪多边形要输入多边形的顶点数及各顶 点x,y坐标。 <2)裁剪前与裁剪后的结果输出在活动窗口中。 附加要求: 对于裁剪多边形可由用户控制裁剪的边逐边裁剪。 三、实验所用仪表及设备 使用实验室提供的PC机。 使用VisualC++编程。 四、实验步骤 1.编码法裁剪二维线段 已知线段端点的区域码,就可以判断直线与裁剪窗口之间的关系。 <1)如果两端点的编码均为0000,直线在窗口内。 <2)如果两端点的编码相与不为0000,表示直线在窗口外。 <3)否则对端点编码,根据从右到左<或从左到右)顺序判别编码位是否为1,确定与窗口求交的边界并求出交点,裁剪线段,将交点作为直线的新端点,重复以上<1)<2)步骤。 jLBHrnAILg 例如上图直线: a.左端点1的编码0101,右端点2的编码1010。 b.符合<3),计算交点。 c.设从左端点开始,因为1号端点的编码为0101,从左边开始,第一位是1,所以与左边界有交点,求交点3。 d.计算3号点的编码为0000。 e.3号点与2号点的关系仍符合<3)。 f.由于3号点的编码为0000,已在窗口内,再从右端2号点开始计算交点,因为2号端点的编码为1010,从左边开始,第二位是1,所以与右边界有交点,求交点4,其编码为1000。 xHAQX74J0X g.3号点与4号点的关系仍符合<3)。 h.由于4号端点的编码为1000,从左边开始,第四位是1,所以与上边界有交点,求交点5,其编码为0000。 LDAYtRyKfE i.3号点与5号点的关系符合<1),结束。 Cohen-SutherLand裁剪算法伪程序如下: #defineLEFT1//0001,左 #defineRIGHT2//0010,右 #defineBOTTOM4//0100,下 #defineTOP8//1000,上 //已知端点坐标 2.设计思路 a)设计菜单函数 直线菜单函数 裁剪菜单函数 b)设计绘画窗口 装载位图函数 定义画笔绘制窗口 定义画笔绘制直线 c)设计裁剪函数 d)设计端点编码函数 3.程序主代码 //MyCutView.cpp: implementationoftheCMyCutViewclassZzz6ZB2Ltk // #include"stdafx.h" #include"MyCut.h" #include"MyCutDoc.h" #include"MyCutView.h" #defineROUND(a>int(a+0.5> #ifdef_DEBUG #definenewDEBUG_NEW #undefTHIS_FILE staticcharTHIS_FILE[]=__FILE__。 #endif #defineLEFT1 #defineRIGHT2 #defineBOTTOM4 #defineTOP8 /////////////////////////////////////////////////////////////////////////////dvzfvkwMI1 //CMyCutView IMPLEMENT_DYNCREATE(CMyCutView,CView> BEGIN_MESSAGE_MAP(CMyCutView,CView> //{{AFX_MSG_MAP(CMyCutView> ON_COMMAND(ID_MENUITEMdrawline,OnMENUITEMdrawline>rqyn14ZNXI 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: : OnFilePrint>EmxvxOtOco ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView: : OnFilePrintPreview>SixE2yXPq5 END_MESSAGE_MAP(> /////////////////////////////////////////////////////////////////////////////6ewMyirQFL //CMyCutViewconstruction/destruction CMyCutView: : CMyCutView(> { //TODO: addconstructioncodehere wxl=200。 wxr=850。 wyb=200。 wyt=450。 m_attatch=FALSE。 m_i=0。 m_draw=FALSE。 RC0=0。 RC1=0。 } CMyCutView: : ~CMyCutView(> { } OOLCMyCutView: : PreCreateWindow(CREATESTRUCT&cs> { //TODO: ModifytheWindowclassorstylesherebymodifyingkavU42VRUs //theCREATESTRUCTcs returnCView: : PreCreateWindow(cs>。 } /////////////////////////////////////////////////////////////////////////////y6v3ALoS89 //CMyCutViewdrawing voidCMyCutView: : OnDraw(CDC*pDC> { CMyCutDoc*pDoc=GetDocument(>。 ASSERT_VALID(pDoc>。 //TODO: adddrawcodefornativedatahere //装载位图 CRectRect。 GetClientRect(&Rect>。 //获得客户区的大小 CBitmapBitmap,*pBitmap。 Bitmap.LoadBitmap(IDB_BITMAP1>。 CDCMemDC。 MemDC.CreateCompatibleDC(GetDC(>>。 pBitmap=MemDC.SelectObject(&Bitmap>。 MemDC.BitBlt(0,0,Rect.Width(>,Rect.Height(>,&Picture,0,0,SRCCOPY>。 M2ub6vSTnP MemDC.TextOut((wxl+wxr>/2,wyb-20,"窗口">。 //窗口标题 //绘制窗口和直线 CPenPen3,*pOldPen3。 //定义3个像素宽度的画笔 Pen3.CreatePen(PS_SOLID,3,RGB(0,0,0>>。 pOldPen3=MemDC.SelectObject(&Pen3>。 MemDC.MoveTo(wxl,wyt>。 MemDC.LineTo(wxr,wyt>。 MemDC.LineTo(wxr,wyb>。 MemDC.LineTo(wxl,wyb>。 MemDC.LineTo(wxl,wyt>。 MemDC.SelectObject(pOldPen3>。 0YujCfmUCw Pen3.DeleteObject(>。 CPenPen1,*pOldPen1。 //定义1个像素宽度的画笔 Pen1.CreatePen(PS_SOLID,1,RGB(0,0,255>>。 pOldPen1=MemDC.SelectObject(&Pen1>。 if(m_i>=1> { MemDC.MoveTo(ROUND(Pointx[0]>,ROUND(Pointy[0]>>。 MemDC.LineTo(ROUND(Pointx[1]>,ROUND(Pointy[1]>>。 } MemDC.SelectObject(pOldPen1>。 Pen1.DeleteObject(>。 CDC*dc=GetDC(>。 dc->BitBlt(0,0,Rect.Width(>,Rect.Height(>,&MemDC,0,0,SRCCOPY>。 eUts8ZQVRd MemDC.SelectObject(pBitmap>。 } /////////////////////////////////////////////////////////////////////////////sQsAEJkW5T //CMyCutViewprinting BOOLCMyCutView: : OnPreparePrinting(CPrintInfo*pInfo>GMsIasNXkA { //defaultpreparation returnDoPreparePrinting(pInfo>。 } voidCMyCutView: : OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/>TIrRGchYzg { //TODO: addextrainitializationbeforeprinting } voidCMyCutView: : OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/>7EqZcWLZNX { //TODO: addcleanupafterprinting } /////////////////////////////////////////////////////////////////////////////lzq7IGf02E //CMyCutViewdiagnostics #ifdef_DEBUG voidCMyCutView: : AssertValid(>const { CView: : AssertValid(>。 } voidCMyCutView: : Dump(CDumpContext&dc>const { CView: : Dump(dc>。 } CMyCutDoc*CMyCutView: : GetDocument(>//non-debugversionisinlinezvpgeqJ1hk { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyCutDoc>>>。 NrpoJac3v1 return(CMyCutDoc*>m_pDocument。 } #endif//_DEBUG /////////////////////////////////////////////////////////////////////////////1nowfTG4KI //CMyCutViewmessagehandlers voidCMyCutView: : OnMENUITEMdrawline(> { //TODO: Addyourcommandhandlercodehere if(FALSE==m_attatch> { Picture.CreateCompatibleDC(GetDC(>>。 CBitmap*Bitmap,*pBitmap。 Bitmap=newCBitmap。 //Bitmap->LoadBitmap(IDB_BITMAP1>。 pBitmap=Picture.SelectObject(Bitmap>。 m_attatch=TRUE。 } m_draw=TRUE。 m_i=0。 Invalidate(FALSE>。 AfxGetMainWnd(>->SetWindowText("Cohen-Sutherland直线裁剪算法">。 //显示标题fjnFLDa5Zo MessageBox("请使用鼠标在屏幕上绘制直线,然后点击裁剪按钮进行裁剪","提示",MB_OKCANCEL>。 tfnNhnE6e5 } voidCMyCutView: : OnMENUITEMclip(>//裁剪菜单函数 { //TODO: Addyourcommandhandlercodehere Cut(>。 Invalidate(FALSE>。 } voidCMyCutView: : OnLButtonDown(UINTnFlags,CPointpoint>HbmVN777sL { //TODO: Addyourmessagehandlercodehereand/orcalldefaultV7l4jRB8Hs if(TRUE==m_draw> { if(m_i<2> { Pointx[m_i]=point.x。 Pointy[m_i]=point.y。 m_i++。 } } CView: : OnLButtonDown(nFlags,point>。 } voidCMyCutView: : OnMouseMove(UINTnFlags,CPointpoint>83lcPA59W9 { //TODO: Addyourmessagehandlercodehereand/orcalldefaultmZkklkzaaP if(TRUE==m_draw> { if(m_i<2> { Pointx[m_i]=point.x。 Pointy[m_i]=point.y。 Invalidate(FALSE>。 } } CView: : OnMouseMove(nFlags,point>。 } voidCMyCutView: : Cut(> { BOOLChange。 doublex,y。 RC0=EnCode(Pointx[0],Pointy[0]>。 RC1=EnCode(Pointx
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 实验 报告