You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从带曲线的图形中获取均匀分布的点?

实现曲线上点的均匀分布

要让点沿曲线均匀分布,不能直接用numpy.interp对x/y坐标插值——因为它是基于坐标轴的线性插值,没法保证沿曲线的弧长均匀。正确思路是先计算曲线的累计弧长,再基于弧长做均匀采样,最后用numpy.interp映射回坐标。

步骤1:计算曲线的累计弧长

先把原始坐标转成numpy数组,再计算相邻点的距离并累加,得到从起点到每个点的弧长:

x = np.array(x_values)
y = np.array(y_values)

# 计算相邻点的欧氏距离
dx = np.diff(x)
dy = np.diff(y)
segment_lengths = np.sqrt(dx**2 + dy**2)

# 生成累计弧长数组(起点弧长为0)
cumulative_lengths = np.concatenate([[0], np.cumsum(segment_lengths)])
total_curve_length = cumulative_lengths[-1]

步骤2:生成均匀的弧长采样点

指定要生成的均匀点数量,用np.linspace生成从0到总弧长的等间距值:

# 示例:生成50个均匀点
target_point_count = 50
uniform_arc_lengths = np.linspace(0, total_curve_length, target_point_count)

步骤3:用numpy.interp插值得到均匀坐标

这一步才用到numpy.interp,参数对应关系和说明:

  • x:传入我们生成的uniform_arc_lengths(要插值的目标弧长)
  • xp:传入cumulative_lengths(原始点的累计弧长,必须单调递增)
  • fp:传入原始的x或y坐标数组(要插值的目标坐标)
  • period:因为你的曲线是闭合的,设置为total_curve_length,让首尾插值连续,避免断点
  • left/right:我们的采样范围刚好覆盖原始弧长区间,无需设置

代码实现:

# 对x、y坐标分别插值
uniform_x = np.interp(uniform_arc_lengths, cumulative_lengths, x, period=total_curve_length)
uniform_y = np.interp(uniform_arc_lengths, cumulative_lengths, y, period=total_curve_length)

完整代码与效果对比

整合所有代码,对比原始点和均匀点的分布:

from matplotlib import pyplot as plt
import numpy as np

x_values = [1321.4, 598.6, 580.6, 563.8, 548.6, 535.4, 524.5, 516.2, 511,
509.2, 509.2, 511, 516.2, 524.5, 535.4, 548.6, 563.8, 580.6, 598.6, 1321.4, 1339.4,
1356.2, 1371.4, 1384.6, 1395.5, 1403.8, 1409, 1410.8, 1410.8, 1409, 1403.8, 1395.5,
1384.6, 1371.4, 1356.2, 1339.4, 1321.4]
y_values = [805.4, 805.4, 803.5, 798.3, 790.1,
779.2, 766, 750.8, 734, 716, 364, 346, 329.2, 314, 300.8, 289.9, 281.7, 276.5, 274.6,
274.6, 276.5, 281.7, 289.9, 300.8, 314, 329.2, 346, 364, 716, 734, 750.8, 766, 779.2,
790.1, 798.3, 803.5, 805.4]

# 转换为numpy数组
x = np.array(x_values)
y = np.array(y_values)

# 计算累计弧长
dx = np.diff(x)
dy = np.diff(y)
segment_lengths = np.sqrt(dx**2 + dy**2)
cumulative_lengths = np.concatenate([[0], np.cumsum(segment_lengths)])
total_curve_length = cumulative_lengths[-1]

# 生成均匀弧长采样点
target_point_count = 50
uniform_arc_lengths = np.linspace(0, total_curve_length, target_point_count)

# 插值得到均匀坐标
uniform_x = np.interp(uniform_arc_lengths, cumulative_lengths, x, period=total_curve_length)
uniform_y = np.interp(uniform_arc_lengths, cumulative_lengths, y, period=total_curve_length)

# 绘图对比
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))

# 原始点分布
ax1.plot(x, y, color='gray')
ax1.scatter(x, y, color='blue', label='原始点')
ax1.set_aspect('equal')
ax1.set_title('原始点分布')
ax1.legend()

# 均匀点分布
ax2.plot(x, y, color='gray', alpha=0.5)
ax2.scatter(uniform_x, uniform_y, color='red', label='均匀点')
ax2.set_aspect('equal')
ax2.set_title('均匀分布点')
ax2.legend()

plt.show()

numpy.interp参数补充说明

  • x:必须是一维数组,代表需要插值的自变量值(这里是均匀弧长)
  • xp:必须是单调递增的一维数组,代表原始数据的自变量(这里是累计弧长)
  • fp:和xp长度相同的一维数组,代表原始数据的因变量(这里是x/y坐标)
  • period:设置后,插值会按周期重复,适合闭合曲线,避免首尾衔接处的断裂
  • left/right:当x中存在超出xp范围的数值时,返回的默认值;我们的采样范围刚好匹配,所以不用设置

内容的提问来源于stack exchange,提问作者Dr. Pontchartrain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 10:50:25