Bresenham算法
1.0<k<1,x0<x1;
d=k;
d<0.5 取下方点 x++; d=d+k;
d>=0.5 取上方点 x++;y++; d=d+k-1;
程序:
x=x0;y=y0; putpixel(x,y,Red);d=k;
while(x<x1){
if(d<0.5){
x++;d=d+k}
else{x++;y++; d=d+k-1;}
}
改进:令e=d-0.5 ------------------ e=k-0.5;e=e+k;e=e+k-1;
左右都乘2△x ------------------
2△xe=2△y-△x;2△x=2△xe+2△y;2△ex=2△xe+2△y-2△x;
再用2△xe替换e
e=2△y-△x;
e=e+2△y;
e=e+2△y-2△x;
优点:整数运算,速度快;便于硬件实现;
void Bresenham(){
double x,y,deltax,deltay,e;
x=x1;y=y1;deltax=abs(x2-x1);deltay=abs(y2-y1);
e=2*deltay-deltax;
putpixel(x,y,c);
for(int i=0;i<deltax;i++){
if(e<0){
x++;e=e+2*deltay;}
else{
x++;y++;e=e+2*deltay-2*deltax;
}
putpixel(x,y);
}
}
}
中点画圆法
起点(0,R) 终点(x,y)
P(Xp,Yp) p1:(Xp+1,Yp)
p2:(Xp+1,Yp-1);
M(Xp+1,Yp-0.5)
d0=F(1,R-0.5)=1.25-R;
F(x,y)=x方+y方+R方;
F(M)<0 在圆内 取p1;d=d+2*Xp+3;x++;
F(M)>0 在圆外 取p2; d=d+2*(Xp-Yp)+5;x++;y--;
令e=d-0.25; e=1-R;
d<0-------- d-0.25<-0.25;e<-0.25;-------(int)e---------e<0;
e<0;e=e+2*Xp+3;
e>0;e=e+2*(Xp-Yp)+5;
void Circlr(){
int x,y;
int deltax,deltay;
int e=1-R;
x=0;y=R;deltax=3;deltay=2-2*R;
putpixel((xc+x),(yc+y),c);……putpixel((xc-y),(yc-x),c);while(x<y){
if(e<0){
e=e+deltax;deltax=deltax+2;
}else{
e=e+deltax+deltay;deltax=deltax+2;deltay=deltay+2;
y--;
}
x++;
putpixel((xc+x),(yc+y),c);……putpixel((xc-y),(yc-x),c);}
}
椭圆画法:
1.将椭圆分为上半部分与下半部分;
b2(x+1)<a2(y-0.5)
F(x,y)=b*b*x*x+a*a*y*y-a*a*b*b;
F(x,y)>0 在圆外;d>0 取P(x+1,y);
F(x,y)<0在圆内; d<0 取P(x+1,y-1)
d=F(x+1,y-0.5)=....
d<0 d=F(x+2,y-0.5)=d+b*b*(2*x+3);
d>0 d=F(x+2,y-1.5)=d+b*b*(2*x+3)+a*a(-2*y+2);
d0=F(1,b-0.5)=b*b+a*a*(-b+0.25);
voidEllipse(){
x=0;y=b;
d=b*b+a*a*(-b+0.25);
if(b2(x+1)<a2(y-0.5)){
if(d<0){
d=d+b*b*(2*x+3);x++
}else{
d=d+b*b*(2*x+3)+a*a(-2*y+2);
x++;y--;
}
putpixel(x+xc,yc+y,c);
putpixel(-x+xc,yc+y,c);
putpixel(x+xc,yc-y,c);
putpixel(-x+xc,yc-y,c);
}
d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;
else if(y>0){
if(d>0){
d2+=a*a*(-2*y+3);
x++;y--;
}else{
d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;
}
putpixel(x+xc,yc+y,c);
putpixel(-x+xc,yc+y,c);
putpixel(x+xc,yc-y,c);
putpixel(-x+xc,yc-y,c);
}
}