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

如何使用Python或numpy实现沿路径移动连通点并输出新点集

实现方案(纯numpy实现,效率更高)

前置假设输入结构

  • 所有路径存储为list[np.ndarray],每个路径数组shape为(路径顶点数, 2),按路径连通顺序存储顶点x/y坐标
  • 待移动点的属性存储为三个同长数组:
    • point_path_idx:shape为(点总数,), 每个元素对应点所属的路径索引
    • point_t:shape为(点总数,), 每个元素是对应点在所属路径上的归一化位置参数,取值范围[0, 1],0对应路径起点,1对应路径终点
    • move_step:shape为(点总数,), 每个元素是对应点单次移动的归一化步长,正数沿路径正向移动,负数反向移动

核心代码

import numpy as np

def move_points_along_paths(paths: list[np.ndarray], point_path_idx: np.ndarray, point_t: np.ndarray, move_step: np.ndarray, loop: bool=False) -> tuple[np.ndarray, np.ndarray]:
    """
    沿路径移动点,返回新的点坐标和更新后的位置参数t
    :param loop: 点移动到路径端点后是否循环,False则停在端点,True则从另一端重新进入
    """
    num_points = len(point_path_idx)
    new_points = np.zeros((num_points, 2), dtype=np.float32)
    new_point_t = np.clip(point_t + move_step, 0.0, 1.0) if not loop else (point_t + move_step) % 1.0

    # 预计算所有路径的归一化累计长度和各段向量
    path_cum_lens = []
    path_seg_vecs = []
    for path in paths:
        seg_vec = np.diff(path, axis=0)
        seg_len = np.linalg.norm(seg_vec, axis=1)
        cum_len = np.concatenate([[0], np.cumsum(seg_len)])
        norm_cum_len = cum_len / cum_len[-1]
        path_cum_lens.append(norm_cum_len)
        path_seg_vecs.append(seg_vec)
    
    # 逐点插值计算新坐标
    for i in range(num_points):
        path_idx = point_path_idx[i]
        t = new_point_t[i]
        path = paths[path_idx]
        norm_cum_len = path_cum_lens[path_idx]
        seg_vec = path_seg_vecs[path_idx]

        # 匹配t对应的路径段
        seg_idx = np.searchsorted(norm_cum_len, t, side='right') - 1
        seg_idx = np.clip(seg_idx, 0, len(norm_cum_len)-2)
        # 计算段内插值比例
        seg_t = (t - norm_cum_len[seg_idx]) / (norm_cum_len[seg_idx+1] - norm_cum_len[seg_idx])
        # 得到新坐标
        new_points[i] = path[seg_idx] + seg_t * seg_vec[seg_idx]
    
    return new_points, new_point_t

调用示例

# 测试:创建两条L型路径
path1 = np.array([[0,0], [10,0], [10,10]], dtype=np.float32)
path2 = np.array([[0,10], [10,10], [10,0]], dtype=np.float32)
paths = [path1, path2]

# 测试点:2个点分别属于两条路径,初始位置为路径的0.2处,单次移动步长0.1
point_path_idx = np.array([0, 1], dtype=np.int32)
point_t = np.array([0.2, 0.2], dtype=np.float32)
move_step = np.array([0.1, 0.1], dtype=np.float32)

new_coords, new_t = move_points_along_paths(paths, point_path_idx, point_t, move_step)
print("移动后的点坐标:\n", new_coords)

如果你没有提前标注每个点所属的路径和初始位置t,可以额外加一步投影匹配:对每个点遍历所有路径的线段,计算点到线段的最短距离,找到距离最小的线段所属的路径,再计算投影点对应的归一化t值即可,该步骤也可纯numpy实现。

内容的提问来源于stack exchange,提问作者Tortenrandband

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:36:03