如何检查3D点是否在圆柱体内

问题描述 投票:3回答:1

给定两个3d点和另一个3d点列表,我想检查哪一个在圆柱体内定义为两个点之间的半径为r的三维线。我已经实现了一个数值解决方案,这是不准确和太慢:

def point_in_cylinder(pt1, pt2, points, r, N=100):
    dist = np.linalg.norm(pt1 - pt2)
    ori = (pt2 - pt1) / dist 
    line = np.array([pt1 + ori*t for t in np.linspace(0, dist, N)])
    dists = np.min(cdist(line, points), 0)
    return np.where(dists <= r)[0]

我相信有更好的解决方案......

*****编辑*****

我通过用矩阵乘法替换listcomp(声明行的位置)来加速这个函数:

line = (pt1.reshape(3, 1) + elc_ori.reshape(3, 1) @ np.linspace(0, dist, N).reshape(1, N)).T
python numpy 3d
1个回答
7
投票

(根据我的理解)您正在圆柱体内部创建一个离散(且非常大)的均匀间隔点列表,然后检查测试点到轴向点的最小距离是否在圆柱体的半径范围内。


这很慢,因为这些测试中的每一个都具有复杂性O(N),当它可以在O(1)中完成时(见后文)。但最重要的是:

这是不准确的,因为您正在测试的空间区域不会填满整个圆柱体!

下图说明了原因(请原谅质量不好):

enter image description here

正如您所看到的,圆柱表面附近的白色空间在测试中给出了假阴性。为了减少这种不准确性,你需要增加N,这反过来会使算法效率降低。

[即使您使用(理论上)无限多个点,测试区域仍将会聚到一个胶囊,而不是整个圆柱体。


一个O(1)方法将是:

  • 鉴于测试点q,检查: enter image description here 这将证实q位于圆柱体的两个圆形面的平面之间。
  • 接下来检查: enter image description here 这将证实q位于圆柱体的曲面内。

编辑:试图在numpy中实现(如果有错误,请告诉我)

def points_in_cylinder(pt1, pt2, r, q):
    vec = pt2 - pt1
    const = r * np.linalg.norm(vec)
    return np.where(np.dot(q - pt1, vec) >= 0 and np.dot(q - pt2, vec) <= 0 \ 
           and np.linalg.norm(np.cross(q - pt1, vec)) <= const)
© www.soinside.com 2019 - 2024. All rights reserved.