import numpy as np def perpendicular_distance(point, start, end): """計算點到線段的垂直距離""" if np.array_equal(start, end): return np.linalg.norm(point - start) # 計算線段的向量 line_vec = end - start line_len = np.linalg.norm(line_vec) line_unit_vec = line_vec / line_len # 計算點到起點的向量 point_vec = point - start projection_length = np.dot(point_vec, line_unit_vec) if projection_length < 0: closest_point = start elif projection_length > line_len: closest_point = end else: closest_point = start + projection_length * line_unit_vec return np.linalg.norm(point - closest_point) def ramer_douglas_peucker(points, epsilon): """Ramer-Douglas-Peucker 演算法""" # 找到最遠的點 start, end = points[0], points[-1] dmax = 0.0 index = -1 for i in range(1, len(points) - 1): d = perpendicular_distance(points[i], start, end) if d > dmax: index = i dmax = d # 如果最大距離大於 epsilon,則遞歸 if dmax > epsilon: # 遞歸 left = ramer_douglas_peucker(points[:index+1], epsilon) right = ramer_douglas_peucker(points[index:], epsilon) return np.concatenate((left[:-1], right)) # 去除重複的點 else: return np.array([start, end]) # 示例數據 y_values = [你的曲線數值] # 替換為你的數據 x_values = np.arange(len(y_values)) points = np.column_stack((x_values, y_values)) # 設定 epsilon 值 epsilon = 0.1 # 調整此值以控制簡化程度 # 簡化曲線 simplified_points = ramer_douglas_peucker(points, epsilon) # 顯示結果 import matplotlib.pyplot as plt plt.plot(x_values, y_values, label='原始曲線') plt.plot(simplified_points[:, 0], simplified_points[:, 1], 'r-', label='簡化曲線') plt.legend() plt.show()