Bresenham原理详见这篇:Bresenham求圆上各点坐标
算法步骤:
1、输入直线的两端点(x,y),(n,m);
2、计算初始值sx,sy,d=0.5-k(but 由于计算机不擅长计算小数,所以,让d*2,再将k写成sy/sx,得:d=sx-2*sy;
3、判断d,若d<0将d更新为d+=2*sx-2*sy;否则d-=2*sy;
4、当直线还没画完,继续3步骤;
(当然忘补充了,上面的步骤只是适合k在[0,1]的,对于k>1的,改变一下增量方向就行了,说人话就是把公式里的dx、dy调换一下。。。。。不过放心,早就为你想好了,下面代码是支持全斜率,其具体推导过程结合对称性自己求一求就出来了,实在不行就自己推一推也能出来。
#include<stdio.h>
int main() {
int x,y,n,m;
scanf("%d%d%d%d",&x,&y,&n,&m);
int sx=n-x;
int sy=m-y;
if(sy>sx) {//斜率大于 1 的直线,转换坐标,以y作为自增量,x作为因增量
m>y?:(m^=(y^=(m^=y)),n^=(x^=(n^=x)));//防止坐标大小反了,要不然结果错干净净的,所以检查并调换一下坐标;
int d=sy-2*sx;
int a=x;
for(int i=y; i<=m; ++i) {
printf("%d %d\n",a,i);
if(d<0) {
a++;
d+=2*sy-2*sx;
} else {
d-=2*sx;
}
}
} else if(1.*sy/sx>=0) {//斜率大于0但小于 1
n>x?:(m^=(y^=(m^=y)),n^=(x^=(n^=x)));
int d=sx-2*sy;
int b=y;
for(int i=x; i<=n; ++i) {
printf("%d %d\n",i,b);
if(d<0) {
b++;
d+=2*sx-2*sy;
} else {
d-=2*sy;
}
}
} else if(1.*sy/sx>-1) {//斜率大于-1但小于0
n>x?:(m^=(y^=(m^=y)),n^=(x^=(n^=x)));
int d=-sx-2*sy;
int b=y;
for(int i=x; i<=n; ++i) {
printf("%d %d\n",i,b);
if(d>0) {
b--;
d-=(2*sx+2*sy);
} else {
d-=2*sy;
}
}
} else {//剩下的就知道啦!!!!!
m>y?:(m^=(y^=(m^=y)),n^=(x^=(n^=x)));
int d=-sy-2*sx;
int a=x;
for(int i=y; i<=m; ++i) {
printf("%d %d\n",a,i);
if(d<0) {
a--;
d-=2*sy+2*sx;
} else {
d-=2*sx;
}
}
}
return 0;
}