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

如何在Python中按距离阈值分组距离较近的3D点?

3D点按距离阈值分组的实现方案

算法简易指引

  • 初始化剩余点集为原始点的副本,避免修改原数据
  • 初始化分组列表,用于存储最终的点组
  • 循环处理剩余点集,直到为空:
    • 取出剩余点集中的第一个点作为当前组的核心点
    • 遍历剩余点,筛选出所有与核心点的欧氏距离≤设定阈值的点,组成当前分组
    • 从剩余点集中移除这些已分组的点
    • 将当前分组加入分组列表
  • 若需要将单个点归为未分组,可在最后对分组列表做筛选:保留点数≥2的组,将单点点组的点归入未分组列表

示例代码

纯Python实现(无需额外库)

import math

def group_3d_points(points, distance_threshold, single_point_as_ungrouped=True):
    # 复制原始点集,避免修改输入数据
    remaining_points = points.copy()
    groups = []
    
    while remaining_points:
        # 取第一个点作为当前组的核心点
        core_point = remaining_points[0]
        current_group = []
        to_remove = []
        
        # 遍历剩余点,计算欧氏距离并筛选符合条件的点
        for idx, point in enumerate(remaining_points):
            distance = math.sqrt(
                (point[0] - core_point[0])**2 +
                (point[1] - core_point[1])**2 +
                (point[2] - core_point[2])**2
            )
            if distance <= distance_threshold:
                current_group.append(point)
                to_remove.append(idx)
        
        # 倒序删除已分组的点,避免索引错乱
        for idx in reversed(to_remove):
            del remaining_points[idx]
        
        groups.append(current_group)
    
    # 区分单点点组和有效分组
    if single_point_as_ungrouped:
        valid_groups = []
        ungrouped = []
        for group in groups:
            if len(group) > 1:
                valid_groups.append(group)
            else:
                ungrouped.extend(group)
        return valid_groups, ungrouped
    else:
        return groups, remaining_points

# 测试示例
if __name__ == "__main__":
    sample_points = [
        (0, 0, 0), (0.1, 0.1, 0.1), (10, 10, 10),
        (10.2, 10.3, 10.1), (20, 20, 20)
    ]
    threshold = 1.0
    
    groups, ungrouped = group_3d_points(sample_points, threshold)
    
    print("有效分组:")
    for i, group in enumerate(groups):
        print(f"组{i+1}: {group}")
    print(f"未分组点:{ungrouped}")

用Numpy简化计算(代码更简洁)

如果可以安装Numpy库(执行pip install numpy即可),用向量运算能简化距离计算:

import numpy as np

def group_3d_points_np(points, distance_threshold, single_point_as_ungrouped=True):
    remaining_points = np.array(points)
    groups = []
    
    while len(remaining_points) > 0:
        core_point = remaining_points[0]
        # 批量计算所有点与核心点的欧氏距离
        distances = np.linalg.norm(remaining_points - core_point, axis=1)
        # 筛选符合距离阈值的点
        mask = distances <= distance_threshold
        current_group = remaining_points[mask].tolist()
        # 更新剩余点集
        remaining_points = remaining_points[~mask]
        groups.append(current_group)
    
    # 区分单点点组和有效分组
    if single_point_as_ungrouped:
        valid_groups = []
        ungrouped = []
        for group in groups:
            if len(group) > 1:
                valid_groups.append(group)
            else:
                ungrouped.extend(group)
        return valid_groups, ungrouped
    else:
        return groups, remaining_points.tolist()

# 测试示例
if __name__ == "__main__":
    sample_points = [
        (0, 0, 0), (0.1, 0.1, 0.1), (10, 10, 10),
        (10.2, 10.3, 10.1), (20, 20, 20)
    ]
    threshold = 1.0
    
    groups, ungrouped = group_3d_points_np(sample_points, threshold)
    
    print("有效分组:")
    for i, group in enumerate(groups):
        print(f"组{i+1}: {group}")
    print(f"未分组点:{ungrouped}")

说明

  • 纯Python版本无需额外依赖,逻辑直观,适合快速理解
  • Numpy版本利用批量运算,处理几千个点的速度完全够用,代码更简洁
  • 通过single_point_as_ungrouped参数可以切换是否将单个点视为未分组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:57:22