道格拉斯-普客抽稀算法及测试(python动态图解)
道格拉斯-普客抽稀算法的动态图解
·
一、简介
二、代码
分享给有需要的人,代码质量勿喷
import numpy as np
import math
import operator
import laspy
import matplotlib.pyplot as plt
class xjPoint():
def __init__(self, x, y, z, ID):
self.x = x
self.y = y
self.z = z
self.ID = ID
def DP(dataX, dataY, Tdis):
point_count = len(dataX)
k = (dataY[point_count-1]-dataY[0]) / (dataX[point_count-1]-dataX[0])
b = dataY[0] - k * dataX[0]
dis_max = -1
dis_max_index = -1
for i in range(point_count):
dis = abs(k*dataX[i]+b-dataY[i]) / math.sqrt(k*k+1)
# region plot processing(仅仅是绘制过程----------------------------------------)
ax.cla()
ax.set_title("Douglas-Peuker")
ax.set_xlabel("x")
ax.set_ylabel("y")
buffer = 1
plt.xlim(min(X) - buffer, max(X) + buffer)
plt.ylim(min(Y) - buffer, max(Y) + buffer)
plt.grid(True)
# all points
ax.scatter(X, Y, color='k', label='data')
# points
ax.scatter(dataX, dataY, color='b',label='current section')
# SE Line
plt.plot([dataX[0], dataX[point_count - 1]], [dataY[0], dataY[point_count - 1]], "r",
label='Start-End Line')
# current point
plt.plot(dataX[i], dataY[i], "go", markersize=10, label='current point')
# plt.text(min(data_X)+2, min(data_Y)+4, str(round(dis,3)), fontdict={'size': 15, 'color': 'g'})
#当前段的节点
plt.plot(dataX[dis_max_index], dataY[dis_max_index], "ro", markersize=10,
label='point_max_dis')
# 所有已确定的节点
plt.plot(resultX, resultY, "r*", markersize=12, label='Node')
plt.legend()
plt.pause(0.1)
# endregion
if dis>=dis_max:
dis_max = dis
dis_max_index = i
if dis_max>Tdis:
resultX.append(dataX[dis_max_index])
resultY.append(dataY[dis_max_index])
dataXX1 = dataX[0:dis_max_index+1]
dataYY1 = dataY[0:dis_max_index+1]
DP(dataXX1, dataYY1, Tdis)
dataXX2 = dataX[dis_max_index:point_count]
dataYY2 = dataY[dis_max_index:point_count]
DP(dataXX2, dataYY2, Tdis)
if __name__ == '__main__':
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
#region 1 acquire data from las(自己定义数据也可以,但是要排好顺序----------------------)
# 读
f = laspy.read('a.las')
# 偏移值
lasHeader = f.header
offsetX = lasHeader.offset[0]
offsetY = lasHeader.offset[1]
data_all = []
maxX = maxY = -99999999
minX = minY = 99999999
for i in range(lasHeader.point_records_count):
p = xjPoint(f.x[i] - offsetX, f.y[i] - offsetY, f.z[i], i)
data_all.append(p)
#region 判断XY最大最小值
if f.x[i]>=maxX:
maxX = f.x[i]
if f.x[i]<minX:
minX = f.x[i]
if f.y[i]>=maxY:
maxY = f.y[i]
if f.y[i]<minY:
minY = f.y[i]
#endregion
#region sort by scale (x or y) important
if (maxX-minX)>=(maxY-minY):
collation = operator.attrgetter('x', 'ID')
data_all.sort(key=collation)
else:
collation = operator.attrgetter('y', 'ID')
data_all.sort(key=collation)
#endregion
X = []
Y = []
for i in range(len(data_all)):
X.append(data_all[i].x)
Y.append(data_all[i].y)
#endregion
#region 2 DP(--------------------------=------------------------------)
resultX = []
resultY = []
resultX.append(X[0])
resultY.append(Y[0])
T_DIS = 2
DP(X, Y, T_DIS)
resultX.append(X[len(X)-1])
resultY.append(Y[len(Y)-1])
#endregion
# region 3 plot result(-----------------------------------)
ax.cla()
ax.set_title("Douglas-Peuker")
ax.set_xlabel("x")
ax.set_ylabel("y")
buffer = 1
plt.xlim(min(X) - buffer, max(X) + buffer)
plt.ylim(min(Y) - buffer, max(Y) + buffer)
plt.grid(True)
# data
ax.scatter(X, Y, color='k', label='data')
#节点与连线
plt.plot(resultX, resultY, "r*", markersize=12, label='Node')
plt.plot(resultX, resultY, "r", linestyle="dashed", label='Line')
plt.legend()
plt.show()
# endregion
三、试验结果
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献6条内容
所有评论(0)