实验二++圆与椭圆.docx
- 文档编号:27955878
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:11
- 大小:43.61KB
实验二++圆与椭圆.docx
《实验二++圆与椭圆.docx》由会员分享,可在线阅读,更多相关《实验二++圆与椭圆.docx(11页珍藏版)》请在冰豆网上搜索。
实验二++圆与椭圆
实验二圆与椭圆
实验2圆与椭圆
给出圆心坐标(x,y)和半径r,逐点画出一个圆周的公式有下cc
列两种。
一直角坐标法
直角坐标系的圆的方程为
222()()xxyyr,,,,cc
由上式导出:
22yyrxx,,,,()cc
当x–x从–r到r做加1递增时,就可以求出对应的圆周点的c
y坐标。
但是这样求出的圆周上的点是不均匀的,|x–x|越大,c对应生成圆周点之间的圆周距离也就越长。
因此,所生成的圆不美观。
二中点画圆法
222P=(x,y)pp如图1所示,函数为F(x,y)=x+y–R
的构造圆,圆上的点为F(x,y)=0,圆外的M点F(x,y)>0,圆内的点F(x,y)<0,构造
P2判别式:
22d=F(M)=F(x+1,y–0.5)=(x+1)+(y–0.5)ppppP1若d,0,则应取P为下一像素,而且1
图1中点画圆法示意图下一像素的判别式为
222d=F(x+2,y–0.5)=(x+2)+(y–0.5)–R=d+2x+3ppppp
若d?
0,则应取P为下一像素,而且下一像素的判别式为2222d=F(x+2,y–1.5)=(x+2)+(y–1.5)–R=d+2(x–y)+5pppppp
我们讨论按顺时针方向生成第二个八分圆,则第一个像素是(0,R),判别式d的初始值为
d=F(1,R–0.5)=1.25–R0
y三圆的Bresenham算法
yid1设圆的半径为r,先考虑圆心
y在(0,0),从x=0、y=r开始的顺时d2–1yi
针方向的1/8圆周的生成过程。
在
xxOxii+1
图2确定y的位置
这种情况下,x每步增加1,从x=0开始,到x=y结束,即有xi+1=x+1;相应的,y则在两种可能中选择:
y=y或者y=y–ii+1i+1ii+1i1。
选择的原则是考察精确值y是靠近y还是靠近y–1(见图2),ii计算式为
222y=r–(x+1)i22222d=y–y=y–r+(x+1)1iii22222d=y–(y–1)=r–(x+1)–(y–1)2iii
令p=d–d,并代入d、d,则有i1212
2222p=2(x+1)+y+(y–1)–2r(1.6)iiii
p称为误差。
如果p,0,则y=y,否则y=y–1。
iii+1ii+1i
p的递归式为i
22p=p+4x+6+2(y+1–y)–2(y+1–y)(1.7)i+1iiiiii
p的初值由式(1.6)代入x=0,y=r,得iii
p=3–2r(1.8)1
根据上面的推导,圆周生成算法思想如下:
(1)求误差初值,p=3–2r,i=1,画点(0,r)。
1
(2)求下一个光栅位置,其中x=x+1,如果p,0则y=y,i+1iii+1i否则y=y–1。
i+1i
(3)画点(x,y)。
i+1i+1
(4)计算下一个误差,如果p,0则p=p+4x+6,否则ii+1iip=p+4(x–y)+10。
i+1iii
(5)i=i+1,如果x=y则结束,否则返回步骤
(2)。
程序设计步骤如下。
(1)创建应用程序框架,以上面建立的单文档程序框架为基础。
(2)编辑菜单资源。
在工作区的ResourceView标签
中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根图3程序主菜单据表1中的定义添加编辑菜单资源。
此时建好的菜单如图3所示。
表1菜单资源表
菜单标题菜单项标题标示符ID
中点画圆ID_MIDPOINTCIRCLE
圆
ID_BRESENHAMCIRCLEBresenham画圆
(3)添加消息处理函数。
利用ClassWizard(建立类向导)为应用程序添加与菜单项
相关的消息处理函数,ClassName栏中选择CMyView,根据表
2建立如下的消息映射函数,ClassWizard会自动完成有关的函
数声明。
表2菜单项的消息处理函数
菜单项ID消息消息处理函数
CONMMAOnMidpointcircleID_MIDPOINTCIRCLEN
ID_BRESENHAMCIRCLCONMMAOnBresenhamcircl
ENe
(4)程序结构代码,在CMyView.cpp文件中的相应位置添加
如下代码。
voidCMyView:
:
OnMidpointcircle()//中点算法
绘制圆,如图4所示
{
//TODO:
Addyourcommandhandlercodehere
CDC*pDC=GetDC();
intxc=300,yc=300,r=50,c=0;
intx,y;图4中点算法绘制圆floatd;
x=0;y=r;d=1.25-r;
pDC->SetPixel((xc+x),(yc+y),c);
pDC->SetPixel((xc-x),(yc+y),c);
pDC->SetPixel((xc+x),(yc-y),c);
pDC->SetPixel((xc-x),(yc-y),c);
pDC->SetPixel((xc+y),(yc+x),c);
pDC->SetPixel((xc-y),(yc+x),c);
pDC->SetPixel((xc+y),(yc-x),c);
pDC->SetPixel((xc-y),(yc-x),c);
while(x<=y)
{if(d<0)d+=2*x+3;
else{d+=2*(x-y)+5;y--;}
x++;
pDC->SetPixel((xc+x),(yc+y),c);
pDC->SetPixel((xc-x),(yc+y),c);
pDC->SetPixel((xc+x),(yc-y),c);
pDC->SetPixel((xc-x),(yc-y),c);
pDC->SetPixel((xc+y),(yc+x),c);
pDC->SetPixel((xc-y),(yc+x),c);
pDC->SetPixel((xc+y),(yc-x),c);
pDC->SetPixel((xc-y),(yc-x),c);
}
}
voidCMyView:
:
OnBresenhamcircle()////
Bresenham算法绘制圆,如图5所示
{
CDC*pDC=GetDC();intxc=100,yc=100,
radius=50,c=0;
int
x=0,y=radius,p=3-2*radius;
while(x pDC->SetPixel(xc+x,yc+y,c); pDC->SetPixel(xc-x,yc+y,c); pDC->SetPixel(xc+x,yc-y,c);pDC->SetPixel(xc-x,yc-y,c);pDC->SetPixel(xc+y,yc+x,c);pDC->SetPixel(xc-y,yc+x,c);pDC->SetPixel(xc+y,yc-x,c);pDC->SetPixel(xc-y,yc-x,c);if(p<0) p=p+4*x+6; else { p=p+4*(x-y)+10; y-=1; } x+=1; } if(x==y) pDC->SetPixel(xc+x,yc+y,c);pDC->SetPixel(xc-x,yc+y,c);pDC->SetPixel(xc+x,yc-y,c); pDC->SetPixel(xc-x,yc-y,c);pDC->SetPixel(xc+y,yc+x,c);pDC->SetPixel(xc-y,yc+x,c);pDC->SetPixel(xc+y,yc-x,c);pDC->SetPixel(xc-y,yc-x,c);} 四椭圆扫描转换中点算法 下面讨论椭圆的扫描转换中点算法,设椭圆为中心在坐标原点的标准椭圆,其方程为 222222F(x,y)=bx+ay–ab=0 (1)对于椭圆上的点,有F(x,y)=0; (2)对于椭圆外的点,F(x,y)>0; (3)对于椭圆内的点,F(x,y)<0。 以弧上斜率为–1的点作为分界将 y第一象限椭圆弧分为上下两部分(如 图6所示)。 二分量相等的法向量法向量: 上半部分,,FF22Nxybxay(,)ij2i2j,,,,下半部分,,xyx22bxay (1)(0.5),,,ii图6第一象限的椭圆弧而在下一个点,不等号改变方向,则 说明椭圆弧从上部分转入下部分。 与中点绘制圆算法类似,一个像素确定后,在下面两个候选像素点的中点计算一个判别式的值,再根据判别式符号确定离椭圆最近的点。 先看椭圆弧的上半部分,具体算法如下: x,yx假设横坐标为的像素中与椭圆最近点为(),下一对ppp x+1y–0.5候选像素的中点应为(,),判别式为pp222222dFxybxayab,,,,,,,,(1,0.5) (1)(0.5)pppp1 d,01,表明中点在椭圆内,应取正右方像素点,判别式变为 2222222,dFxybxayabdbx,,,,,,,,,,,(2,0.5) (2)(0.5)(23)ppppp11 d,01若,表明中点在椭圆外,应取右下方像素点,判别式变 为 222222,dFxybxayab,,,,,,,,(2,1.5) (2)(1.5)pppp1222(23)(22),,,,,,dbxaypp1 d1(0,b)(1,b判别式的初始条件确定。 椭圆弧起点为,第一个中点为 –0.5),对应判别式为 2222222dFbbababbab,,,,,,,,,,(1,0.5)(0.5)(0.25)10 在扫描转换椭圆的上半部分时,在每步迭代中需要比较法向量的两个分量来确定核实从上部分转到下半部分。 在下半部分算法有些不同,要从正上方和右下方两个像素中选择下一个像素。 在从上半部分转到下半部分时,还需要对下半部分的中点判别式 (x,y)进行初始化。 即若上半部分所选择的最后一个像素点为,pp x+0.5,y–1则下半部分中点判别式应在()的点上计算。 其在正pp 下方与右下方的增量计算同上半部分。 具体算法的实现请参考下 面的程序设计。 程序设计步骤如下。 (1)创建应用程序框架,以上面建立的单文档程序框架为基础。 (2)编辑菜单资源。 在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表3中的定义添加编辑菜单资源。 此时建好的菜单如图7所示。 表3菜单资源表 菜单标题菜单项标题标示符ID ID_MIDPOINTE椭圆中点画椭圆LLISPE 图7程序主菜单 (3)添加消息处理函数。 利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CMyView,根据表4建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。 表4菜单项的消息处理函数 菜单项ID消息消息处理函数ID_MIDPOINTELLISPECONMMANOnMidpointellispe(4)程序结构代码如下: voidCMyView: : OnMidpointellispe()//中点算 法绘制椭圆,如图8所示 { CDC*pDC=GetDC(); int图8中点算法绘制椭圆 a=200,b=100,xc=300,yc=200,c= 0; intx,y; doubled1,d2; x=0;y=b; d1=b*b+a*a*(-b+0.25); pDC->SetPixel(x+300,y+200,c); pDC->SetPixel(-x+300,y+200,c); pDC->SetPixel(x+300,-y+200,c); pDC->SetPixel(-x+300,-y+200,c);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 椭圆
![提示](https://static.bdocx.com/images/bang_tan.gif)