图形学_椭圆扫描转换_中点椭圆算法
中点椭圆算法
(1)先讨论椭圆弧的上部分
设(Xp,Yp)已确定,则下一待选像素的中点是(Xp+1,Yp-0.5)
d1=F(Xp+1,Yp-0.5)= b2(Xp+1)2+a2(Yp-0.5)2-a2b2
根据d1的符号来决定下一像素是取正右方的那个,还是右上方的那个。
若d1<0,中点在椭圆内,取正右方象素,判别式更新为:
d1‘=F(Xp+2,Yp-0.5)=d1+b2(2Xp+3)
d1的增量为b2(2Xp+3)
当d1≥0,中点在椭圆外,取右下方象素,更新判别式:
d1‘=F(Xp+2,Yp-1.5)=d1+b2(2Xp+3)+a2(-2Yp+2)
d1的增量为b2(2Xp+3)+a2(-2Yp+2)
(2)d1的初始条件:椭圆弧起点为(0,b);
第一个中点为(1,b-0.5)
初始判别式:d1=F(1,b-0.5)=b*b+a*a(-b+0.25)
(3)转入下一部分,下一象素可能是正下方或右下方,
此时判别式要初始化
d2 = F(Xp+0.5,Yp-1) = b2(Xp+0.5)2+a2(Yp-1)2-a2b2
若d2<0,取右下方像素,则d2‘ = F(Xp+1.5,Yp-2) = d2 + b2(2Xp+2)+a2(-2Yp+3)
若d2>=0,取正下方像素,则d2‘ = F(Xp+0.5,Yp-2) = d2 + a2(-2Yp+3)
下半部分弧的终止条件为 y = 0
1 //椭圆的中点画法 2 3 #include "easyx.h" 4 #include "math.h" 5 #include "windows.h" 6 #include "stdio.h" 7 #include "stdlib.h" 8 #include "conio.h" 9 #include "graphics.h" 10 11 int Draw_tuoyuan(int a,int b,int p1,int p2,int color) 12 { 13 int x,y; 14 double d1,d2; 15 x = 0; 16 y = b; 17 d1 = b*b+a*a*(-b+0.25); 18 putpixel(x+p1,y+p2,color); 19 while(b*b*(x+1) < a*a*(y-0.5)) 20 { 21 if(d1 < 0) 22 { 23 d1 += b*b*(2*x+3); 24 x++; 25 } 26 else 27 { 28 d1 += (b*b*(2*x+3) + a*a*(-2*y+2)); 29 x++; 30 y--; 31 } 32 putpixel(x+p1,y+p2,color); 33 putpixel(x+p1,-y+p2,color); 34 putpixel(-x+p1,y+p2,color); 35 putpixel(-x+p1,-y+p2,color); 36 37 } //上半部分绘制完毕 38 39 d2 = sqrt(b*(x+0.5)) + sqrt(a*(y-1)) - sqrt(a*b); 40 while(y > 0) 41 { 42 if(d2 < 0) 43 { 44 d2 += b*b*(2*x+2) + a*a*(-2*y+3); 45 x++; 46 y--; 47 } 48 else 49 { 50 d2 += a*a*(-2*y+3); 51 y--; 52 } 53 putpixel(x+p1,y+p2,color); 54 putpixel(x+p1,-y+p2,color); 55 putpixel(-x+p1,y+p2,color); 56 putpixel(-x+p1,-y+p2,color); 57 } //下半部分绘制完毕 58 59 60 return 0; 61 } 62 63 64 65 66 int main() 67 { 68 //硬件测试,将gd装入图形驱动器,gm置入最大图形模式。 69 int gd=DETECT,gm,a,b,p1,p2,color; 70 printf("椭圆的中点画法\n"); 71 printf("请输入长半轴和短半轴:"); 72 scanf("%d%d",&a,&b); 73 printf("请输入椭圆圆心坐标:"); 74 scanf("%d%d",&p1,&p2); 75 printf("请输入颜色:"); 76 scanf("%d",&color); 77 78 //图形初始化 79 initgraph(&gd,&gm,"c:\\tc"); 80 //设置兰背景。 81 setbkcolor(BLUE); 82 cleardevice(); 83 84 Draw_tuoyuan(a,b,p1,p2,color); 85 86 getch(); 87 closegraph(); 88 89 return 0; 90 }