计算机图形学画多边形(2)

2021-09-24 12:04

(1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。

(2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入“基本图形的生成”作为工程名称,单击“确定”按钮,出现Step 1对话框。

(3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。

(4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。

(5)在Step 6对话框中单击“完成”按钮,即完成“基本图形的生成”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-5所示,单击“确定”按钮,完成应用程序框架的创建。

图1-5 信息程序基本

3.编辑菜单资源

设计如图1-4所示的菜单项。在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-1中的定义编辑菜单资源。此时VC已自动建好程序框架,如图1-5所示。

表1-1菜单资源表

4.添加消息处理函数

利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,

ClassName栏中选择CMyView,根据表1-2建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。

表1-2菜单项的消息处理函数

5.程序结构代码,在CMyView.cpp文件中相应位置添加如下代码:

// DDA算法生成直线

void CMyView:: OnDdaline()

{

CDC* pDC=GetDC();//获得设备指针

int xa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);//定义直线的两端点,直线颜色

int x,y;

float dx, dy, k;

dx=(float)(xb-xa), dy=(float)(yb-ya);

k=dy/dx, y=ya;

if(abs(k)<1)

{

for (x=xa;x<=xb;x++)

{pDC->SetPixel (x,int(y+0.5),c);

y=y+k;}

}

if(abs(k)>=1)

{

for (y=ya;y<=yb;y++)

{pDC->SetPixel (int(x+0.5),y,c);

x=x+1/k;}

}

ReleaseDC(pDC);

}

说明:

(1)以上代码理论上通过定义直线的两端点,可得到任意端点之间的一直线,但由于一般屏幕坐标采用右手系坐标,屏幕上只有正的x, y值,屏幕坐标与窗口坐标之间转换知识请参考第3章。

(2)注意上述程序考虑到当k 1的情形x每增加1,y最多增加1;当k>1时,y每增加1,x相应增加1/k。在这个算法中,y与k用浮点数表示,而且每一步都要对y进行四舍五入后取整。

//中点算法生成直线

void CMyView::OnMidpointline()

{

CDC* pDC=GetDC();

int xa=300, ya=200, xb=450, yb=300,c=RGB(0,255,0);

float a, b, d1, d2, d, x, y;

a=ya-yb, b=xb-xa, d=2*a+b;

d1=2*a, d2=2* (a+b);

x=xa, y=ya;

pDC->SetPixel(x, y, c);

while (x<xb)

{ if (d<0) {x++, y++, d+=d2; }

else {x++, d+=d1;}

pDC->SetPixel(x, y, c);

}

ReleaseDC(pDC);

}

说明:

(1)其中d是x p, y p的线性函数。为了提高运算效率,程序中采用增量计算。具体算法如下:若当前像素处于d>0情况,则取正右方像素P1(x p+1, y p),判断下一个像素点的位置,应计算d1=F(x p+2, y p+0.5)=a(x p+2)+b(y p+0.5)=d+a;,其中增量为a。若d<0时,则取右上方像素P2(x p+1, y p+1)。再判断下一像素,则要计算d2= F(x p+2, y p+1.5)=a(x p+2)+b(y p+1.5)+c=d+a+b,增量为a+b。

(2)画线从(x0, y0)开始,d的初值d0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b,因F(x0, y0)=0,则d0=a+0.5b。

(3)程序中只利用d的符号,d的增量都是整数,只是初始值包含小数,用2d代替d,使程序中仅包含整数的运算。

//Bresenham算法生成直线

void CMyView::OnBresenhamline()

{

CDC* pDC=GetDC();

int x1=100, y1=200, x2=350, y2=100,c=RGB(0,0,255);

int i,s1,s2,interchange;

float x,y,deltax,deltay,f,temp;

x=x1;

y=y1;

deltax=abs(x2-x1);

deltay=abs(y2-y1);

if(x2-x1>=0) s1=1; else s1=-1;

if(y2-y1>=0) s2=1; else s2=-1;

if(deltay>deltax){

temp=deltax;

deltax=deltay;

deltay=temp;

interchange=1;

}

else interchange=0; f=2*deltay-deltax; pDC->SetPixel(x,y,c); for(i=1;i<=deltax;i++){ if(f>=0){

if(interchange==1) x+=s1; else y+=s2;

pDC->SetPixel(x,y,c); f=f-2*deltax; } else{

if(interchange==1) y+=s2; else x+=s1; f=f+2*deltay; } } }

说明:

(1)以上程序已经考虑到所有象限直线的生成。 (2)Bresenham 算法的优点如下:

① 不必计算直线的斜率,因此不做除法。 ② 不用浮点数,只用整数。

③ 只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。 ④ Bresenham 算法的运算速度很快。 1.2 圆

给出圆心坐标(x c , y c )和半径r ,逐点画出一个圆周的公式有下列两种。 1.2.1 直角坐标法 直角坐标系的圆的方程为

222()()c c x x y y r -+-=

由上式导出:

=c y y

当x –x c 从–r 到r 做加1递增时,就可以求出对应的圆周点的y 坐标。但是这样求出的圆周上的点是不均匀的,| x –x c | 越大,对应生成圆周点之间的圆周距离也就越长。因此,所生成的圆

M

P 2 P 1

P =(x p , y p )

图1-6 中点画圆法示意图

y y i y y i –1

O x i x i +1 x

1d

2d

图1-7 确定y 的位置

不美观。

1.2.2 中点画圆法

如图1-6所示,函数为F(x, y)=x2+y2–R2的构造圆,圆上的点为F(x, y)=0,圆外的点F(x, y)>0,圆内的点F(x, y)<0,构造判别式:

d=F(M)=F(x p+1, y p–0.5)=(x p+1)2+(y p–0.5)2

若d<0,则应取P1为下一像素,而且下一像素的判别式为

d=F(x p+2, y p–0.5)= (x p+2)2+(y p–0.5)2–R2=d+2x p+3

计算机图形学画多边形(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:英汉语言对比-1-General Introduction of the Course

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: