繁体   English   中英

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

[英]How to check if a 3D point is inside a cylinder

给定两个 3d 点和另一个 3d 点列表,我想检查哪个在圆柱体内,圆柱体定义为半径为 r 的两点之间的 3d 线。 我为此实现了一个数字解决方案,它不准确且速度太慢:

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

(据我所知)您正在圆柱体内其轴上创建一个离散(且相当大)均匀间隔点的列表,然后检查测试点到轴向点的最小距离是否在圆柱的半径内。


这很慢,因为这些测试中的每一个都有复杂度O(N) ,而它可以在O(1) (见下文)。 但最重要的是:

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

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

在此处输入图片说明

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

[即使你使用(理论上)无限数量的点,测试区域仍然会收敛到一个胶囊,而不是整个圆柱体。]


O(1)方法是:

  • 给定一个测试点q ,检查:

    在此处输入图片说明

    这将确认q位于圆柱体的两个圆形面的平面之间。

  • 接下来检查:

    在此处输入图片说明

    这将确认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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM