图形学实验三
贵州大学实验报告 学院:
计信学院 专业:
计科 班级:
计科 101 姓名 罗琳 学号 1008060016 实验组 实验时间 2013-4-8 指导教师 吴云 成绩 实验项目名称 椭圆的生成算法 实验目的 通过本实验,使学生了解并掌握在光栅显示系统中椭圆的生成和显示算法。
实验要求 实现中点椭圆算法。
实验原理 中点算法 算法原理:
中点算法可以推广到一般二次曲线如椭圆。
中心在原点的椭圆方程为:
隐函数的形式为:
a=b 时,该方程表示的是圆。
椭圆具有四对称性,可只考虑第一象限的椭圆弧。
椭圆上任一点(x,y)处2 22 21x ya b y x b a 2 2 2 2 2,()0 F x y b x a y ab x y p(x,y)N上 下的法向量为:
如在 p 点法线两分量相等,则 p 点将椭圆第一象限分成两部份,上半部份法向量在 y方向的分量比 x 方向的大,在下半部份相反。在 p 点:
在当前中点处,法向量(2b 2(Xp+1),2a 2(Yp-0.5))的 y 分量比 x 分量大,即:
b 2(Xp+1)< a 2(Yp-0.5)而在下一中点,不等式改变方向,则说明椭圆弧从上部分转入下部分。
与圆弧中点算法类似:确定一个象素 P i 后,接着在下两个候选象素的中点计算一个判别式 d=F(M)的值,由判别式的符号确定更近的点。
1.先讨论椭圆弧的上半部分(令△x=1)设 P i(x i,y i)已确定,则下一对待选像素的中点是:
M(x i +1,y i-0.5)对初始点(0,b),第一个中点为(1,b-0.5),则:
(1)当 d<0(取 T 点)时,下一点(i+1)点的坐标为(x i +1,Y i),为确定 i+2 点取的下一个中点 M 的坐标为:(x i +2,y i-0.5)(2)当 d>=0(取 B 点)时,下一点(i+1)点的坐标为(x i +1,Y i-1),为确定 i+2 点取的下一个中点 M 的坐标为:(x i +2,Y i-1.5)2.在每一次迭代中都要判断椭圆是否已从上半部进入了下半部,如果 b 2 x>=a 2 y,则椭圆进入下半部份,此时令△y=1,且:
2 2(,)2 2x yF FN x y i j f i f j b xi a y jx y 2 2x yf f or b x a y B M T P i(x i, y i) 2 2 2 2 2 2()1, 0.5(1)(0.5)i i i id F M F x y b x a y a b 2 2011, 0.5()4d F b b a b 22 2 212, 0.5(2 3)(2 3)2new i i old ii id F x y d b xd b x b x b 2 22 2 2 2 21 12, 1.5(2 3)(2 2)(2 3)(2 2)2 2new i i old i ii i i id F x y d b x a yd b x a y b x b a y 22 2 2 2 20(0.5)1 d b x a y a b L M R P i(x i , y i)
(1)若 d<0,取右下方像素 R,则(2)若 d>=0,取正下方像素 L,则 3.终止条件为:y=0 MidpointEllipe(a,b, color)int a,b,color;{ int x,y;float d1,d2;x = 0;y = b;d1 = b*b +a*a*(-b+0.25);putpixel(x,y,color);while(b*b*(x+1)< a*a*(y-0.5)){ { if(d1<0)d1 +=b*b*(2*x+3);x++;} else { d1 +=(b*b*(2*x+3)+a*a*(-2*y+2))x++;y--;} putpixel(x,y,color);}//上部分 d2 = sqr(b*(x+0.5))+sqr(a*(y-1))– sqr(a*b);while(y >0){ if(d2 <0){ d2 +=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;} else {d2 += a*a*(-2*y+3);y--;} putpixel(x,y,color);} //下部分 } 算法 优化(提示):
联解以下方程:
2 22 2 21 1(1.5, 2)(2 2)(2 3)2 2new p pold p pold i id F x yd b x a yd b x a y a 22 21(0.5, 2)(2 3)2new p pold pold id F x yd a yd a y a
得到椭圆上、下部分分界点 P 的坐标为:
(1)令 x 由 0→P x,y 由 0→P y,从而避免上述算法中反复计算循环中止条件。
(2)采用增量算法,避免在计算d时的乘法和平方运算。
实验环境 硬件平台:PC 软件(推荐):Windows平台,Visual C++,matlab 实验步骤 1.掌握算法原理; 2.依据算法,编写源程序并进行调试; 3.对运行结果进行保存与分析; 4.把源程序以文件的形式提交; 5.按格式书写实验报告。
实验内容 实验中的源代码:
void CHuanYuanDlg::OnTuoYuan()//画椭圆函数 { // TODO: Add your control notification handler code here CWnd* pWnd=GetDlgItem(IDC_STATIC);CDC* pDC=pWnd->GetDC();pWnd->Invalidate();pWnd->UpdateWindow();UpdateData(true);int a,b;a=m_a;b=m_b; 2 2 2 2 22 2,()0 F x y b x a y abb x a y 2 22 2 2 2(,)a ba b a b
if(a==0||b==0)MessageBox("请输入椭圆的半径!");else{ int x0=m_x0,y0=m_y0;pDC->SetViewportOrg(x0,y0), //画直角坐标轴 pDC->MoveTo(0,-y0), pDC->LineTo(0,y0), pDC->MoveTo(-x0,0), pDC->LineTo(x0,0);int x,y,a1,b1,a2,b2;double d1,d2,fx,fy;a1=a*a;b1=b*b;a2=2*a1;b2=2*b1;fx=0;fy=a2*b;d1=b1-a1*b+0.25*a1;x=0;y=b;while(fx<=fy){ pDC->SetPixel(x,y,RGB(0,0,255));pDC->SetPixel(-x,y,RGB(0,255,0));pDC->SetPixel(x,-y,RGB(255,0,0));pDC->SetPixel(-x,-y,RGB(255,255,255));x++;fx=fx+b2;
if(d1<0)d1 = d1+fx+b1;else { y--;fy=fy-a2;d1=d1+fx+b1-fy;} } pDC->SetPixel(x,y,RGB(0,0,255));pDC->SetPixel(-x,y,RGB(0,255,0));pDC->SetPixel(x,-y,RGB(255,0,0));pDC->SetPixel(-x,-y,RGB(255,255,255));d2=b1*(x+0.5)*(x+0.5)+a1*(y-1)*(y-1)-a1*b1;while(y>0){ y--;fy=fy-a2;if(d2>=0)d2=d2-fy+a1;else { x++;fx=fx +b2;d2=d2+fx-fy+a1;} pDC->SetPixel(x,y,RGB(0,0,255));pDC->SetPixel(-x,y,RGB(0,255,0));pDC->SetPixel(x,-y,RGB(255,0,0));
pDC->SetPixel(-x,-y,RGB(255,255,255));} } UpdateData(false);} void CHuanYuanDlg::OnDelete(){ // TODO: Add your control notification handler code here Invalidate();} 实验结果 编译、调试并运行程序,结果如下:
实验总结 在上一次实验的基础上,掌握了利用中点算法生成椭圆基本过程,了解并掌握在光栅显示系统中椭圆的生成和显示算法。
指导教师意见 签名:
年 月 日
