Bresenham画线算法
根据两个顶点画线
Bresenham画线算法适用于斜率绝对值小于1的情况,所以要进行翻转,k绝对值小于1的情况下将算法中的x和y换一下即可
#画线算法,参数为(原图像,点1,点2,画线数值)
def draw_line(ori_canvas,x1,y1,x2,y2,color):
canvas=copy.deepcopy(ori_canvas)
delta_x=x2-x1
delta_y=y2-y1
#判断斜率是否存在
if(delta_x==0):
for i in range(min(y1,y2),max(y1,y2)+1):
canvas[x1][i]=color
return canvas
k=1.0*delta_y/delta_x
# 根据斜率<1分类
if(abs(k)<1):
# 固定x增长方向
if(x1>x2):
x1,x2=x2,x1
y1,y2=y2,y1
delta_x=x2-x1
delta_y=y2-y1
x=x1
y=y1
canvas[x][y]=color
# 判断y增长方向
if(k<0):
delta_y=-delta_y
p=2*delta_y-delta_x
for i in range(delta_x):
if(p<0):
x+=1
p+=2*delta_y
else:
x+=1
if(k>0):
y+=1
else:
y-=1
p+=2*delta_y-2*delta_x
canvas[x][y]=color
else:
# 固定y增长方向
if(y1>y2):
x1,x2=x2,x1
y1,y2=y2,y1
delta_x=x2-x1
delta_y=y2-y1
x=x1
y=y1
canvas[x][y]=color
# 判断x增长方向
if(k<0):
delta_x=-delta_x
p=2*delta_x-delta_y
for i in range(delta_y):
if(p<0):
y+=1
p+=2*delta_x
else:
if(k>0):
x+=1
else:
x-=1
y+=1
p+=2*delta_x-2*delta_y
canvas[x][y]=color
return canvas
if(k>0):
y+=1
else:
y-=1
p+=2*delta_y-2*delta_x
canvas[x][y]=color
else:
if(y1>y2):
x1,x2=x2,x1
y1,y2=y2,y1
delta_x=x2-x1
delta_y=y2-y1
x=x1
y=y1
canvas[x][y]=color
if(k<0):
delta_x=-delta_x
p=2*delta_x-delta_y
for i in range(delta_y):
if(p<0):
y+=1
p+=2*delta_x
else:
if(k>0):
x+=1
else:
x-=1
y+=1
p+=2*delta_x-2*delta_y
canvas[x][y]=color
return canvas
# 圆周采集一系列角度
def get_theta_list(points_number):
lis=np.arange(0,points_number)
return 1.0*lis/points_number*2*math.pi
new_canvas=np.zeros([100,100])
theta_list=get_theta_list(12)
point_list=[]
for theta in theta_list:
x=40*math.cos(theta)+50
y=40*math.sin(theta)+50
#print(x,y)
point_list.append([x,y])
for x,y in point_list:
new_canvas=draw_line(new_canvas,50,50,int(x),int(y),1)
#new_canvas=draw_line(canvas,23,12,6,12,1)
plt.figure(figsize=(10, 10))
plt.imshow(new_canvas,cmap='gray')
根据端点以及角度画线
根据端点以及线段方向,计算出射线的最远点,然后使用画线算法
#根据theta角进行画线
def theta_ray(x1,y1,theta,ori_canvas,color):
canvas=copy.deepcopy(ori_canvas)
height=canvas.shape[0]
width=canvas.shape[1]
x2,y2=0,0
#计算沿直线拓展后的边界点
if(abs(math.tan(theta))<1e-3 or abs(math.tan(theta))>1e3): #垂直方向
if(abs(theta-0)<1e-3):
y2=y1
x2=height-1
elif(abs(theta-math.pi/2)<1e-3):
x2=x1
y2=width-1
elif(abs(theta-math.pi)<1e-3):
y2=y1
x2=0
elif(abs(theta-3*math.pi/2)<1e-3):
x2=x1
y2=0
else:
k=math.tan(theta)
#第一象限方向
if(theta>=0 and theta<math.pi/2):
yy=int(y1+k*(height-1-x1))
if(yy<width):
x2=height-1
y2=yy
else:
y2=width-1
x2=int(x1+1/k*(width-1-y1))
#第二象限方向
elif(theta>=math.pi/2 and theta<=math.pi):
yy=int(y1-k*x1)
if(yy<width):
x2=0
y2=yy
else:
y2=width-1
x2=int(x1+1/k*(width-1-y1))
#第三象限方向
elif(theta>=math.pi and theta<3*math.pi/2):
yy=int(y1-k*x1)
if(yy>=0):
x2=0
y2=yy
else:
y2=0
x2=int(x1-1/k*y1)
#第四象限方向
elif(theta>=3*math.pi/2 and theta<2*math.pi):
yy=int(y1+k*(height-1-x1))
if(yy>=0):
x2=height-1
y2=yy
else:
y2=0
x2=int(x1-1/k*y1)
delta_x=x2-x1
delta_y=y2-y1
#判断斜率是否存在
if(delta_x==0):
for i in range(min(y1,y2),max(y1,y2)+1):
canvas[x1][i]=color
return canvas
k=1.0*delta_y/delta_x
# 根据斜率<1分类
if(abs(k)<1):
# 固定x增长方向
if(x1>x2):
x1,x2=x2,x1
y1,y2=y2,y1
delta_x=x2-x1
delta_y=y2-y1
x=x1
y=y1
canvas[x][y]=color
# 判断y增长方向
if(k<0):
delta_y=-delta_y
p=2*delta_y-delta_x
for i in range(delta_x):
if(p<0):
x+=1
p+=2*delta_y
else:
x+=1
if(k>0):
y+=1
else:
y-=1
p+=2*delta_y-2*delta_x
canvas[x][y]=color
else:
# 固定y增长方向
if(y1>y2):
x1,x2=x2,x1
y1,y2=y2,y1
delta_x=x2-x1
delta_y=y2-y1
x=x1
y=y1
canvas[x][y]=color
# 判断x增长方向
if(k<0):
delta_x=-delta_x
p=2*delta_x-delta_y
for i in range(delta_y):
if(p<0):
y+=1
p+=2*delta_x
else:
if(k>0):
x+=1
else:
x-=1
y+=1
p+=2*delta_x-2*delta_y
canvas[x][y]=color
return canvas
pre_theta_list=get_theta_list(20)
mapp=np.zeros([100,100])
for theta in pre_theta_list:
mapp=theta_ray(20,30,theta,mapp,3)
plt.imshow(mapp,cmap='gray')