实验二实验三 基本图形.docx

上传人:b****6 文档编号:3836386 上传时间:2022-11-25 格式:DOCX 页数:16 大小:35.41KB
下载 相关 举报
实验二实验三 基本图形.docx_第1页
第1页 / 共16页
实验二实验三 基本图形.docx_第2页
第2页 / 共16页
实验二实验三 基本图形.docx_第3页
第3页 / 共16页
实验二实验三 基本图形.docx_第4页
第4页 / 共16页
实验二实验三 基本图形.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

实验二实验三 基本图形.docx

《实验二实验三 基本图形.docx》由会员分享,可在线阅读,更多相关《实验二实验三 基本图形.docx(16页珍藏版)》请在冰豆网上搜索。

实验二实验三 基本图形.docx

实验二实验三基本图形

实验二基本图形(元)生成技术

(一)

直线生成算法

一、实验目的

在一个图形系统中,基本图形(也称为图元、图素等)的生成技术是最基本的,任何复杂的图形都是由基本图形组成的,基本图形生成的质量直接影响该图形系统绘图的质量。

所以,需要设计出精确的基本图形生成算法,以确保图形系统绘图的精确性。

本次实验的目的就是验证直线生成的三种扫描算法,并要求对基本算法进行扩充和改进,包括:

利用VisualC++实现三种直线生成算法,验证算法的正确性;

二、实验任务

1.理解三种直线生成算法思想,写出实现程序;

2.添加鼠标功能,实现交互式画直线程序;

3.将10个像素作为步距单位,编出Bresenham算法的示例。

三、基本知识和实验步骤

任务一:

实现DDA画线程序

实验步骤:

1.建立一个DDALine的工程文件;

2.添加ddaline()成员函数

方法:

在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“addmemberfunction…”,定义如下的成员函数:

voidddaline(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor);

3.编写自定义的成员函数ddaline()程序

voidCDDALineView:

:

ddaline(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor)

{

intlength,i;

floatx,y,dx,dy;

length=abs(x1-x0);

if(abs(y1-y0)>length)

length=abs(y1-y0);

dx=(x1-x0)/length;

dy=(y1-y0)/length;

x=x0+0.5;y=y0+0.5;

for(i=1;i<=length;i++)

{

pDC->SetPixel((int)x,(int)y,color);

x=x+dx;y=y+dy;

}

}

4.编写OnDraw()函数

voidCDDALineView:

:

OnDraw(CDC*pDC)

{

CDDALineDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

ddaline(pDC,100,100,400,100,RGB(255,0,0));

ddaline(pDC,400,100,400,400,RGB(0,255,0));

ddaline(pDC,400,400,100,400,RGB(0,0,255));

ddaline(pDC,100,400,100,100,RGB(255,255,0));

ddaline(pDC,100,100,400,400,RGB(255,0,255));

ddaline(pDC,100,400,400,100,RGB(0,255,255));}

}

5.编译、调试和运行程序,查看程序结果。

任务二、放大10倍后,算法演示程序

先画出(100,100)到(600,400)大小为10的网格,然后从(100,100)以10为单位,计算出直线上各个像素位置。

步骤:

1.建立DDA2Line工程;

2.在OnDraw()函数中画出网格,并调用DDA2Line()函数

voidCDDA2LineView:

:

OnDraw(CDC*pDC)

{

CDDA2LineDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

//画网格

intgi,gj;

//画横线

pDC->TextOut(90,90,"(100,100)");

pDC->MoveTo(100,100);

for(gj=100;gj<=400;gj=gj+10)

{

pDC->MoveTo(100,gj);

pDC->LineTo(600,gj);

}

//画竖线

pDC->MoveTo(100,100);

for(gi=100;gi<=600;gi=gi+10)

{

pDC->MoveTo(gi,100);

pDC->LineTo(gi,400);

}

pDC->TextOut(590,410,"(600,400)");

//画出像素点

DDA2line(pDC,100,100,600,400,RGB(255,0,0));

}

3.添加DDA2Line()成员函数

方法:

在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“addmemberfunction…”,定义如下的成员函数:

voidDDA2Line(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor);

4.编写DDA2Line()函数

voidCDDA2LineView:

:

DDA2line(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor)

{

intlength,i,tx,ty;

floatx,y,dx,dy;

length=abs(x1-x0);

if(abs(y1-y0)>length)

length=abs(y1-y0);

dx=(float)(x1-x0)/length;

dy=(float)(y1-y0)/length;

//chartbuf[20];

//sprintf(tbuf,"dx,dy=%f,%f",dx,dy);

//AfxMessageBox(tbuf);

x=x0;y=y0;

for(i=0;i<=length;i=i+10)

{

tx=(int)((x+5)/10)*10;

ty=(int)((y+5)/10)*10;

pDC->SetPixel(tx,ty,color);

pDC->Ellipse(tx-5,ty-5,tx+5,ty+5);

x=x+dx*10;y=y+dy*10;

}

}

5.调试、运行程序

任务三、加入鼠标功能,实现交互式画直线

第一步:

建立DDAMouseLine工程文件;

第二步:

向视图类中添加自定义的成员变量

用鼠标右键单击视图类,选择“AddMemberVariable…”,添加下面三个成员变量。

proctected:

CPointm_p1;//起点

CPointm_p2;//终点

intm_ist;//区别,m_ist=0,表示直线起点,

//m_ist=1,表示直线终点

第三步:

向视图类中添加自定义的成员函数原型:

public:

voidDDAMouseLine(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor);

第四步:

在视图类CPP文件的构造函数中初始化成员变量。

视图类的构造函数名与该视图类的名字相同。

在视图类中选择构造函数,如:

CDDAMouseLineView(),用鼠标左键双击,输入下面程序代码:

CDDAMouseLineView:

:

CDDAMouseLineView()

{

//TODO:

addconstructioncodehere

m_p1.x=0;m_p1.y=0;//起点

m_p2.x=0;m_p2.y=0;//终点

m_ist=0;//0,第1点;1,第2点;

}

第五步:

在视图类的OnDraw()函数中加入下列代码,实现视图绘图。

voidCMouseSpringView:

:

OnDraw(CDC*pDC)

{

CMouseSpringDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

pDC->SelectStockObject(NULL_BRUSH);

DDAMouseLine(pDC,m_p1.x,m_p1.y,m_p2.x,m_p2.y,RGB(255,0,0));

//调用自定义的成员函数,用鼠标画直线

}

第六步:

向视图类中添加鼠标OnLButtonDown()函数消息响应函数,并输入鼠标处理程序代码。

voidCMouseSpringView:

:

OnLButtonDown(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CDC*pDC=GetDC();

pDC->SelectStockObject(NULL_BRUSH);

if(!

m_ist)//是起点

{

m_p1=m_p2=point;//纪录第一次单击鼠标位置,定起点

m_ist++;

}

else

{

m_p2=point;//记录第二次单击鼠标的位置,定终点的点

m_ist--;//为新绘图作准备

DDAMouseLine(pDC,m_p1.x,m_p1.y,m_p2.x,m_p2.y,RGB(255,0,0));//绘制新直线

}

ReleaseDC(pDC);//释放设备环境

CView:

:

OnLButtonDown(nFlags,point);

}

第七步:

添加成员函数的程序代码。

voidCDDAMouseLineView:

:

DDAMouseLine(CDC*pDC,intx0,inty0,intx1,inty1,COLORREFcolor)

{

intlength,i;

floatx,y,dx,dy;

length=abs(x1-x0);

if(abs(y1-y0)>length)

length=abs(y1-y0);

dx=(float)(x1-x0)/length;

dy=(float)(y1-y0)/length;

x=x0+0.5;y=y0+0.5;

for(i=1;i<=length;i++)

{

pDC->SetPixel((int)x,(int)y,color);

x=x+dx;y=y+dy;

}

//pDC->MoveTo(x0,y0);

//pDC->LineTo(x1,y1);

}

第八步:

编译运行程序,验证运行结果。

程序改进,添加橡皮筋绘图技术,实现交互式画直线。

向视图类中添加鼠标OnMouseMove()函数消息响应函数,并输入鼠标处理程序代码。

voidCDDAMouseLineView:

:

OnMouseMove(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CDC*pDC=GetDC();

intnDrawmode=pDC->SetROP2(R2_NOT);//设置异或绘图模式,并保存原来绘图模式

pDC->SelectStockObject(NULL_BRUSH);

if(m_ist==1)

{

CPointprePnt,curPnt;

prePnt=m_p2;//获得鼠标所在的前一位置

curPnt=point;

//绘制橡皮筋线

DDAMouseLine(pDC,m_p1.x,m_p1.y,prePnt.x,prePnt.y,RGB(255,0,0));

//DrawCircle(pDC,m_bO,prePnt);//用异或模式重复画圆,擦出所画的圆

DDAMouseLine(pDC,m_p1.x,m_p1.y,curPnt.x,curPnt.y,RGB(255,0,0));

//DrawCircle(pDC,m_bO,curPnt);//用当前位置作为圆周上的点画圆

m_p2=point;

}

pDC->SetROP2(nDrawmode);//恢复原绘图模式

ReleaseDC(pDC);//释放设备环境

CView:

:

OnMouseMove(nFlags,point);

}

四、实验结果和分析

1.查看实验结果,验证算法的正确性;

2.对程序进行分析和比较,你还能提出哪些改进和扩充?

例如:

(1)线刷子绘制直线和圆;

(2)方形刷子绘制直线和圆;

(3)虚线和点划线的绘制;

五、实验总结

总结从本次实验中学到了那些知识点或者有哪些感受?

实验三基本图形(元)生成技术

(二)

圆、椭圆生成算法

一、实验目的

编写圆和椭圆的扫描转换算法程序,验证算法的正确性。

二、实验任务

1.编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;

2.添加鼠标程序,实现交互式画圆;

3.编写中点画椭圆法的扫描转换程序;

4.添加鼠标程序,实现交互式画椭圆;

三、实验内容

任务一:

中点画圆法的扫描转换算法

编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;

分析:

考虑圆心不再原点,设圆心坐标为(x0,y0)。

通过平移坐标原点到圆心,则第二个8分圆上一点p(x,y),其原始坐标为

x’=x+x0

y’=y+y0

即p’1(x0+x,y+y0)

其它7个对称点分别是:

p’2(x0+y,y+x0),p’3(x0+y,y0-x),p’4(x0+x,y0-y),p’5(x0-x,y0-y),p’6(x0-y,y0-x),p’7(x0-y,y0+x),p’8(x0-x,y0+y)

程序实现步骤:

(1)建立MidPointCircle工程文件;

(2)右击CMidPointCircleView类,建立成员函数

voidMidpointCircle(CDC*pDC,intx0,inty0,intr,COLORREFcolor)

intCirPot(CDC*pDC,intx0,inty0,intx,inty,COLORREFcolor)

(3)编写成员函数代码,程序如下:

voidCMidPointCircleView:

:

MidpointCircle(CDC*pDC,intx0,inty0,intr,COLORREFcolor)

{

//自己补充

}

(4)编写OnDraw(CDC*pDC)函数,程序如下:

voidCMidPointCircleView:

:

OnDraw(CDC*pDC)

{

CMidPointCircleDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

MidpointCircle(pDC,100,100,10,RGB(255,0,0));

MidpointCircle(pDC,500,300,60,RGB(255,255,0));

}

(6)编译、运行程序,查看结果。

任务二:

添加鼠标程序,实现交互式画圆

在任务1的基础上,完成下列步骤:

(1)向视图类中添加自定义的成员变量

用鼠标右键单击视图类,选择“AddMemberVariable…”,添加下面三个成员变量。

proctected:

intm_r;//半径

CPointm_bO;//圆心

CPointm_bR;//圆上的点

intm_ist;//圆心与圆周上点的区别,m_ist=0,表示鼠标左击点为圆心,

//m_ist=1,表示鼠标左击点为圆周上的点

(2)在视图类CPP文件的构造函数中初始化成员变量

CMidPointCircleMouseView:

:

CMidPointCircleMouseView()

{

//TODO:

addconstructioncodehere

m_bO.x=0;m_bO.y=0;//圆心

m_bR.x=0;m_bR.y=0;//圆上的点

m_ist=0;//圆心与圆上的点区别

m_r=0;//圆的半径

}

(3)向视图类中添加自定义的成员函数原型:

public:

intComputeRadius(CPointcenp,CPointardp);

添加成员函数的程序代码:

intCMouseSpringView:

:

ComputeRadius(CPointcenp,CPointardp)

{

intdx=cenp.x-ardp.x;

intdy=cenp.y-ardp.y;

//sqrt()函数的调用,在头文件中加入#include"math.h"

return(int)sqrt(dx*dx+dy*dy);

}

(4)向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。

具体操作方法与鼠标示例1方法相同。

一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。

程序如下:

voidCMidPointCircleMouseView:

:

OnLButtonDown(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CDC*pDC=GetDC();

pDC->SelectStockObject(NULL_BRUSH);

if(!

m_ist)//绘制圆

{

m_bO=m_bR=point;//纪录第一次单击鼠标位置,定圆心

m_ist++;

}

else

{

m_bR=point;//记录第二次单击鼠标的位置,定圆周上的点

m_ist--;//为新绘图作准备

m_r=ComputeRadius(m_bO,m_bR);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));

}

ReleaseDC(pDC);//释放设备环境

CView:

:

OnLButtonDown(nFlags,point);

}

voidCMidPointCircleMouseView:

:

OnMouseMove(UINTnFlags,CPointpoint)

{

//TODO:

Addyourmessagehandlercodehereand/orcalldefault

CDC*pDC=GetDC();

intnDrawmode=pDC->SetROP2(R2_NOT);//设置异或绘图模式,并保存原来绘图模式

pDC->SelectStockObject(NULL_BRUSH);

if(m_ist==1)

{

CPointprePnt,curPnt;

prePnt=m_bR;//获得鼠标所在的前一位置

curPnt=point;

//绘制橡皮筋线

m_r=ComputeRadius(m_bO,prePnt);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));//用异或模式重复画圆,擦出所画的圆

//DrawCircle(pDC,m_bO,prePnt);

m_r=ComputeRadius(m_bO,curPnt);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));//用当前位置作为圆周上的点画圆

m_bR=point;

}

pDC->SetROP2(nDrawmode);//恢复原绘图模式

ReleaseDC(pDC);//释放设备环境

CView:

:

OnMouseMove(nFlags,point);

}

任务三:

编写中点画椭圆法的扫描转换程序

程序实现步骤:

(1)建立MidPointEllise工程文件;

(2)右击CMidPointElliseView类,建立成员函数

voidMidpointEllise(CDC*pDC,intx0,inty0,inta,intb,COLORREFcolor)

(3)编写成员函数代码,程序如下:

voidCMidPointEllipseView:

:

MidpointEllise(CDC*pDC,intx0,inty0,inta,intb,COLORREFcolor)

{

//自己补充

}

(4)编写OnDraw()函数

voidCMidPointEllipseView:

:

OnDraw(CDC*pDC)

{

CMidPointEllipseDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

MidpointEllise(pDC,300,200,50,20,RGB(255,0,0));

}

(5)编译、运行程序。

任务四:

添加鼠标程序,实现交互式画椭圆

程序实现步骤:

(1)~(3)同上,建立MidPointElliseMouse工程文件。

(4)添加成员变量

protected:

intb;

inta;

intm_ist;

CPointCenterPoint;

CPointRightBottom;

CPointLeftTop;

(5)在构造函数中赋初值

CMidPointElliseMouseView:

:

CMidPointElliseMouseView()

{

//TODO:

addconstructioncodehere

LeftTop.x=0;LeftTop.y=0;//左上角坐标初值

RightBottom.x=0;RightBottom.y=0;//右下角坐标初值

CenterPoint.x=0;CenterPoint.y=0;//中心点坐标初值

a=0;b=0;//长轴和短轴长度

m_ist=0;//0:

表示第一点,1:

表示第二点

}

(6)添加OnLButtonDown()函数

voidCMidPointElliseMouseView:

:

OnLButton

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1