沿离散线段路径等距均匀分布标记点的代码问题排查
问题说明
我正在编写一款路径标记点生成程序:输入为定义路径的点列表、目标标记点数量,程序需要沿该路径精确均匀地分布所有标记点。该路径实际为环形路径,但支持指定任意点作为共同起止点,该环形特性不会对算法逻辑产生影响。
算法设计逻辑如下:
- 第一步:累加所有相邻点构成的线段长度,得到路径总长度,再将总长度除以标记点总数,得到相邻标记点的目标间距
- 第二步:沿路径逐段遍历,每行进达到标记点间距的整数倍距离时,就记录对应位置的标记点坐标
当前编写的代码中,路径遍历逻辑看似正确,但实际生成的标记点分布不均匀,也没有精确贴合路径走向。我已使用matplotlib编写可视化代码,绘制标记点的实际落点以复现该问题,相关内容见后续章节。
路径数据
point_data = [ (53.8024, 50.4762), (49.5272, 51.8727), (45.0118, 52.3863), (40.5399, 53.0184), (36.3951, 54.7708), (28.7127, 58.6807), (25.5306, 61.4955), (23.3828, 65.2082), (22.6764, 68.3316), (22.6945, 71.535), (24.6674, 77.6427), (28.8279, 82.4529), (31.5805, 84.0346), (34.7024, 84.8875), (45.9183, 84.5739), (57.0529, 82.9846), (64.2141, 79.1657), (71.089, 74.802), (76.7944, 69.8429), (82.1092, 64.4783), (83.974, 63.3605), (85.2997, 61.5455), (85.7719, 59.4206), (85.0764, 57.3729), (82.0979, 56.0247), (78.878, 55.1062), (73.891, 53.0987), (68.7101, 51.7283), (63.6943, 51.2997), (58.6791, 51.7438), (56.1255, 51.5243), (53.8024, 50.4762), (53.8024, 50.4762)]
路径遍历核心代码
import math number_of_points = 20 def euclid_dist(x1, y1, x2, y2): return ((x1-x2)**2 + (y1-y2)**2)**0.5 def move_point(x0, y0, d, theta_rad): return x0 + d*math.cos(theta_rad), y0 + d*math.sin(theta_rad) total_dist = 0 for i in range(1, len(point_data), 1): x1, y1 = point_data[i - 1] x2, y2 = point_data[i] total_dist += euclid_dist(x1, y1, x2, y2) dist_per_point = total_dist / number_of_points length_left_over = 0 # 上一段路径剩余的未使用长度 results = [] for i in range(1, len(point_data), 1): x1, y1 = point_data[i - 1] x2, y2 = point_data[i] angle_rads = math.atan2(y1-y2, x1-x2) extra_rotation = math.pi / 2 # 90度角度偏移 angle_output = math.degrees((angle_rads + extra_rotation + math.pi) % (2*math.pi) - math.pi) length_of_segment = euclid_dist(x1, y1, x2, y2) distance_to_work_with = length_left_over + length_of_segment current_dist = dist_per_point - length_left_over while distance_to_work_with > dist_per_point: new_point = move_point(x1, y1, current_dist, angle_rads) results.append((new_point[0], new_point[1], angle_output)) current_dist += dist_per_point distance_to_work_with -= dist_per_point length_left_over = distance_to_work_with
可视化代码
import matplotlib.pyplot as plt from matplotlib import collections as mc import numpy as np X = np.array([x for x, _, _ in results]) Y = np.array([y for _, y, _ in results]) plt.scatter(X, Y) for i, (x, y) in enumerate(zip(X, Y)): plt.text(x, y, str(i), color="red", fontsize=12) possible_colors = [(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1)] lines = [] colors = [] for i in range(len(point_data) -1 , 0, -1): x1, y1 = point_data[i - 1] x2, y2 = point_data[i] lines.append(((x1, y1), (x2, y2))) colors.append(possible_colors[i % 3]) lc = mc.LineCollection(lines, colors = colors, linewidths=2) fig, ax = plt.subplots() ax.add_collection(lc) ax.autoscale() ax.margins(0.1) plt.show()
可视化运行结果

内容的提问来源于stack exchange,提问作者the five states
相关产品推荐
相关产品推荐

