作为刚学的新生,怕自己忘记,借此来记录一下。
这里用了opencv来画点
一、数值微分算法(DDA)
依赖于直线的斜截式方程:y=mx+b
其运算步骤:
以给定的直线段的两个端点(x1,y1)和(x2,y2)作为输入参数。
初始化,即x1=x1+0.5,y1=y1+0.5,来保证计算精度。
计算两个端点间的水平和垂直差值的绝对值,dx=abs(x2-x1),dy=(y2-y1)>
选取dx和dy中最大者作为迭代的步数length。
从(x1,y1)开始,确定由前一像素位置生成的下一像素位置递推所需要的增量,并进行递推计算。如果dx>dy,且x1<x2,那么x与y方向上的增量分别为1和m;如果dx>dy,且x1>=x2,那么x和y方向的增量分别为-1和-m;如果dx<=dy,且x1<x2,那么x与y方向上的增量分别为1/m和1;如果dx<=dy,且x1>=x2,那么x与y方向的增量分别为-1/m和-1。
重复5length次。
将求得的像素坐标值取整。
代码如下:
def DDALine(x1,y1,x2,y2):
dx=abs(x2-x1)
dy=abs(y2-y1)
steps=0
if dx>dy:
steps=dx
direction=0//判断方向的如果为0就是x方向为1就是y方向
else:
steps=dy
direction=1
delta_x=float(dx/steps)
delta_y=float(dy/steps)
x=x1+0.5
y=y1+0.5
for i in range(0,int(steps+1)):
if(direction==0):
cv.circle(img,(int(x),int(y+0.5)),0,(0,0,0),2)
else:
cv.circle(img,(int(x+0.5),int(y)),0,(0,0,0),2)
x+=delta_x
y+=delta_y
二、中点画线算法
依赖于直线的一般式方程。
def MidLine(x1,y1,x2,y2):
x = x1
y = y1
a=y1-y2
b=x2-x1
if(b>=0):
cx=1
else:
b=-b
cx=-1
if(a<=0):
cy=1
else:
a=-a
cy=-1
cv.circle(img,(x,y),0,(0,0,0),2)
if(-a<=b):
d=2*a+b
d1=2*a
d2=2*(a+b)
while(x!=x2):
if(d<0):
y=y+cy
d=d+d2
else:
d=d+d1
x=x+cx
cv.circle(img,(x,y),0,(0,0,0),2)
else:
d=a+2*b
d1=2*b
d2=2*(a+b)
while(x!=x2):
if (d < 0):
d = d + d1
else:
x = x + cx
d = d + d2
y = y + cy
cv.circle(img, (x, y), 0, (0, 0, 0), 2)
三、Bresenham算法
与中点画线算法类似
代码:
def BresenhamLine(x1,y1,x2,y2):
dy=y2-y1
dx=x2-x1
x=x1
y=y1
m=dy/dx
e=m-0.5
cv.circle(img, (x, y), 0, (0, 0, 0), 2)
if(dx>=0):
cx=1
else:
cx=-1
if(dy>=0):
cy=1
else:
cy=-1
while(x!=x2):
if(e<0):
if(abs(m)>1):
y=y+cy
e=e+2*abs(dx)
else:
x=x+cx
e=e+2*abs(dy)
else:
if(abs(m)>1):
x=x+cx
y=y+cy
e=e+2*abs(dx)-2*abs(dy)
else:
y=y+cy
x=x+cx
e=e+2*abs(dy)-2*abs(dx)
cv.circle(img, (x, y), 0, (0, 0, 0), 2)
下边是外部函数,用来制造一个纯色画布,调用函数的时候可以自行更改。
img = np.zeros([800, 800, 3], np.uint8)
img = np.zeros([700,700, 3], np.uint8)
img[:,:,0]=np.zeros([700,700])+255
img[:,:,1]=np.ones([700,700])+254
img[:,:,2]=np.ones([700,700])*255
BresenhamLine(24,25,140,624)
plt.imshow(img,origin='lower')//plt.imshow默认是y也是从上到下逐渐增加的,origin=lower是为了让y轴从下到上计数,成为人们熟悉的坐标系。
plt.show()