实验零? Visual C++ 2005绘图系统
地点:土木楼B401机房时间:星期三下午节次:第三大节
一、实验目的:
1. 了解Visual C++ 2005绘图的基本概念
2. 了解Visual C++ 2005绘图环境
3. 掌握用Visual C++ 2005设计绘图项目的基本步骤
4. 掌握用Visual C++ 2005绘图的基本命令
二、实验内容:
实验内容1:创建绘图应用程序主框架
实验内容2:应用程序编译运行
实验内容3:设置菜单项并生成消息响应函数
实验内容4:SetPixel绘图
三、实验步骤:
实验内容1:创建绘图应用程序主框架
步骤:
1.创建一个工作目录D:\MyProject
2.启动Visual Studio 2005
3.单击“文件”->“新建”->“项目”,项目类型对话框中选择“其他语言”->“VC++”->“MFC”,模版选择“MFC应用程序”。在工作目录D:\MyProject 下创建一个新应用项目: Sample,如下图所示。4.单击“确定”按钮。
5.单击“下一步”按钮。
6.在“应用程序类型中”,选择“单文档”类型。
7.单击“完成”,创建了一项空的工程-绘图应用程序主框架。
实验内容2:应用程序编译运行
运行版本有两类:Debug、Release, 生成Debug解决方案步骤如下:
1.生成解决方案
点击“生成-〉生成解决方案”, 生成了Debug版的可运行程序。
2.调试运行程序
点击菜单“调试——〉开始执行(不调试)”, 执行Debug版的可运行程序。
结果如下:
生成Release解决方案步骤如下:
1.生成解决方案
点击“生成-〉批生成”。
2.勾选“Release”,单击“生成”,生成可以独立于Visual C++ 2005外运行的.exe程序。
3.查看目录,sample.exe是Release版,单击即可以运行。
运行结果:
实验内容3:设置菜单项并生成消息响应函数
1.弹出菜单设计器
双击“资源视图”中的“Menu”展开文件夹,双击“IDR_MAINFRAME”,弹出菜单设计器。右健单击菜单设计器的“帮助”,选择“新插入”,插入一项菜单。
在新插入的菜单项的“Caption”中输入“绘图”。
3.输入ID
输入“打开”菜单项,输入“直线”菜单项,在“直线”菜单项下输入“DDA”菜单,“DDA”菜单的ID为ID_LINE_DDA。
4
单击菜单“视图-〉类视图”,
在“解决方案管理器”窗口中出现“类视图”窗口。
4.生成菜单消息响应函数
在类视图窗口,单击Csample0View类,单击事件按钮,
5.选择ID_LINE_DDA的COMMAND,添加OnLineDDA事件。
6.进入代码编辑器
在void Csample0View::OnLineDda()中的// TODO: 在此添加命令处理程序代码处输入的自己代码:AfxMessageBox("Hello World",MB_OK,NULL);
7.修改项目字符集属性
选择“项目”菜单->属性->,弹出“属性”对话框,选择“配置属性->常规->字符集”,改为“未设置”。
8.运行结果
重新生成解决方案,运行结果如下。
实验内容4:SetPixel绘图
在void Csample0View::OnLineDda()中的 // TODO: 在此添加命令处理程序代码处输入的代码:
// TODO: Add your command handler code here
CClientDC *pdc=new CClientDC(this);
CPen pen;
pen.CreatePen(PS_DOT,1,RGB(255,0,0));
CPen *oldpen=(CPen*)pdc->SelectObject(&pen);
int x,y;
y=100;
for(x=100;x<=300;x+=3){
y++;
pdc->SetPixelV(x,y,RGB(255,0,0));
}
pdc->DeleteDC();
}
运行结果如下。
四、实验结果:
实验内容1:创建绘图应用程序主框架结果
实验内容2:应用程序编译运行结果
实验内容3:设置菜单项并生成消息响应函数
实验内容4:SetPixel绘图
解释以下每条命令的含义
CClientDC *pdc=new CClientDC(this);//定义一个指针类型的CClientDC对象,客户区设备上下文用于客
//户区的输出,与特定窗口关联
CPen pen;//定义一个画笔对象
pen.CreatePen(PS_DOT,1,RGB(255,0,0));//赋予pen对象以风格
CPen *oldpen=(CPen*)pdc->SelectObject(&pen);//
pdc->SetPixelV(x,y,RGB(255,0,0));//画出像素坐标为(x,y),风格为红色的一点
六、其它的实验内容:
答:工具条按钮的添加
七、实验中发现的问题及你解决的方法:
答:发现的问题:调试过程中出现如下错误
解决的方法:重新生成解决方案,如还出现则多生成几次。
实验一直线的生成算法
地点:土木楼B401机房时间:星期三下午节次:第三大节
一、实验目的:
1.理解DDA算法
2.理解中点Bresenham算法
3.理解改进的Bresenham算法
4.了解DDA和Bresenham算法的区别,以及生成图形的差异原因
二、实验内容:
实验内容1:设计DDA算法程序
实验内容2:设计中点Bresenham算法程序
实验内容3:改进的Bresenham算法
三、实验步骤:
实验内容1:设计DDA算法程序
添加函数:void DDALine(int Xa, int Ya, int Xb, int Yb)
//DDA算法
void CSampleView::DDALine(int Xa, int Ya, int Xb, int Yb)
{
CClientDC *pdc=new CClientDC(this);
CPen pen;
pen.CreatePen(PS_DOT,1,RGB(255,0,0));
CPen *oldpen=(CPen*)pdc->SelectObject(&pen);
float delta_x,delta_y;int x,y;
int dx,dy,steps,k;
dx=Xb-Xa;
dy=Yb-Ya;
if(abs(dx)>abs(dy))
steps=abs(dx);
delta_y=(float)dy/(float)steps;
x=Xa;
y=Ya;
pdc->SetPixelV(x,y,RGB(255,0,0));
for(k=1;k<=steps;k++)
{
x+=(int)delta_x;
y+=(int)delta_y;
pdc->SetPixelV(x,y,RGB(255,0,0));
}
pdc->DeleteDC();
}
添加事件响应函数:
// 消息响应函数DDA算法程序的设计画直线
void CSampleView::OnDdaLine()
{
DDALine(100,100,300,300);
}
实验内容2:设计中点Bresenham算法程序
添加函数:void LineBresenhams(int Xa,int Ya,int Xb,int Yb)
//Bresenhams算法程序的设计画直线的实现
void CSampleView::LineBresenhams(int Xa,int Ya,int Xb,int Yb) { CClientDC *pdc=new CClientDC(this);
CPen pen;
pen.CreatePen(PS_DOT,1,RGB(255,0,0));
CPen *oldpen=(CPen*)pdc->SelectObject(&pen);
int dx=abs(Xa-Xb);
int dy=abs(Ya-Yb);
int p=2*dy-dx;
int twody=2*dy;
int twodydx = 2*(dy-dx);
int x,y,xend;
if(Xa>Xb)
{ x=Xb; y=Yb;
xend=Xa;
}
else
{
x=Xa;y=Ya;
xend=Xb;
}
pdc->SetPixelV(x,y,RGB(255,0,0));;
while(x { x++; if(p<0) p+=twody; y++; p+=twodydx; } pdc->SetPixelV(x,y,RGB(255,0,0));; } }添加事件响应函数: void CSampleView::OnBresenhamline() { // TODO: 在此添加命令处理程序代码 LineBresenhams(100,200,300,300); } 实验内容3:改进的Bresenham算法 添加函数:void ImproveBresenhams(int Xa, int Ya, int Xb, int Yb) //Bresenham算法改进算法的实现 void CSampleView::ImproveBresenhams(int Xa, int Ya, int Xb, int Yb) { CClientDC *pdc=new CClientDC(this); CPen pen; pen.CreatePen(PS_DOT,1,RGB(255,0,0)); CPen *oldpen=(CPen*)pdc->SelectObject(&pen); int dx,dy,e,x,y; dx=Xb-Xa; dy=Yb-Ya; e=-dx; x=Xa; y=Ya; while(x<=Xb){ pdc->SetPixelV(x,y,RGB(255,0,0));; x++; e+=2*dy; if(e>0){ y++; e-=2*dx; } } } 添加事件响应函数: //菜单响应函数生成直线ImproveBresenhams算法 void CSampleView::OnImprove() { // TODO: 在此添加命令处理程序代码 ImproveBresenhams(200,100,300,300); } 四、实验结果: 实验内容1:设计DDA算法程序 实验内容2:设计中点Bresenham算法程序 实验内容3:改进的Bresenham算法 DDA算法的缺点是什么? 答:DDA算法的缺点是:它的y和斜率k必须用浮点数表示,而且每一步都必须对y进行舍入取整,这不利于用硬件实现。 六、其它的实验内容: 答:添加工具栏按钮DDA,Bresenham,Bresenham改进画直线 在SampleView.cpp中添加代码: ON_COMMAND(ID_BUTTONDDALine,OnDda) ON_COMMAND(ID_BUTTONBresenham,OnBresenham) ON_COMMAND(ID_BUTTONImprovedBresenham,OnImprovedbresenham) 调试点击工具栏按钮查看效果。 七、实验中发现的问题及你解决的方法: 发现的问题:在生成Release文件时出现错误,但调试时没有错误。 解决的方法:查了资料,现在还没有解决。 实验二:圆和椭圆的生成算法 地点: B401机房时间:星期四节次:第一大节 一、实验目的: 1、了解Bresenham法生成圆和椭圆方法 2、掌握Bresenham生成圆和椭圆算法的基本思想、推导和算法 二、实验内容: 实验内容1:Bresenham法生成圆 实验内容2:Bresenham法生成椭圆 三、实验步骤: 实验内容1:Bresenham法生成圆 步骤1:添加菜单“实验二”,子菜单如下:圆 ID_Circle 步骤2:在SampleView类中添加函数bool CircleLine(x1,y1,r) 实现代码: bool CSampleView::CircleLine(int x1, int y1, int r) { x = 0; y = r; d = 3 - 2 * r; while(x < y) { pdc->SetPixelV(x+x1,y+y1,RGB(255,0,0)); pdc->SetPixelV(y+x1,x+y1,RGB(255,0,0)); pdc->SetPixelV(-y+x1,x+y1,RGB(255,0,0)); pdc->SetPixelV(-x+x1,-y+y1,RGB(255,0,0)); pdc->SetPixelV(-x+x1,y+y1,RGB(255,0,0)); pdc->SetPixelV(-y+x1,-x+y1,RGB(255,0,0)); pdc->SetPixelV(y+x1,-x+y1,RGB(255,0,0)); pdc->SetPixelV(x+x1,-y+y1,RGB(255,0,0)); if(d < 0) d += 4 * x + 6; else { d += 4 * (x - y) + 10; y --; } x ++; } if(x == y) { pdc->SetPixelV(x+x1,y+y1,RGB(255,0,0)); pdc->SetPixelV(y+x1,x+y1,RGB(255,0,0)); pdc->SetPixelV(-y+x1,x+y1,RGB(255,0,0)); pdc->SetPixelV(-x+x1,-y+y1,RGB(255,0,0)); pdc->SetPixelV(-x+x1,y+y1,RGB(255,0,0)); pdc->SetPixelV(-y+x1,-x+y1,RGB(255,0,0)); pdc->SetPixelV(y+x1,-x+y1,RGB(255,0,0)); pdc->SetPixelV(x+x1,-y+y1,RGB(255,0,0)); } return true; } 步骤3;添加画圆菜单响应函数: void CSampleView::OnCircle() { // TODO: 在此添加命令处理程序代码 CircleLine(200,200,100); } 步骤四:调试运行。 实验内容2:Bresenham法生成椭圆 步骤1:添加菜单“实验二”,子菜单如下:椭圆:ID_Ellipse 步骤2:在SampleView类中添加函数void Ellipse(int x1,int y1,int a, int b) 实现代码: // 画椭圆的函数 void CSampleView::Ellipse(int x1,int y1,int a, int b) { int x,y; x=0; y=b; d1=b*b+a*a*(-b+0.25); pdc->SetPixelV(x+x1 ,y+y1 ,RGB(255,0,0)); pdc->SetPixelV(-x+x1 ,-y+y1 ,RGB(255,0,0)); pdc->SetPixelV(x+x1 ,-y+y1,RGB(255,0,0)); pdc->SetPixelV(-x+x1 ,y+y1,RGB(255,0,0));