如何在给定点距离的任意垂直线上找到 3-D 中的点

How to find a point in 3-D at an arbitrary perpendicular line given distance to the point

提问人:Lori 提问时间:12/31/2018 最后编辑:Lori 更新时间:12/31/2018 访问量:218

问:

我有一行 AB。我想画一条垂直于 AB 的线 BC。我知道 A 点和 B 点的 xyz,我也知道 B 和 C 之间的距离 N。如何找到适合给定参数的任意点 C?计算应在 3-D 中完成。任何垂直于 AB 的点都可以是点 C,如果它与 B 的距离等于 N。

这里给出了一个几乎相同的问题,但我想知道在 3D 中是如何完成同样的事情的:你如何在给定的垂直距离处找到一个点?

在上面的链接中给出了对我有用的 2-D 计算:

dx = A.x-B.x
dy = A.y-B.y
dist = sqrt(dx*dx + dy*dy)
dx /= dist
dy /= dist
C.x = B.x + N*dy
C.y = B.y - N*dx

我尝试像这样添加 Z 轴:

dz = A.z - B.z 
dist = sqrt(dx*dx + dy*dy + dz*dz) 
dz /=dist 
C.z = .... at this point it becomes a mystery to me

如果我在 C.z 中输入类似“C.z - N*dz”的东西,距离仅在某些旋转角度下是准确的,我想知道正确的解决方案。我可以想象,在3D中,它是以完全不同的方式计算的。

澄清

  • C点并非唯一。它可以是上的任何点,其 中心位于 B 和半径 N。垂直于 AB
数学 图形 3D 几何 与语言无关

评论

0赞 Aziz 12/31/2018
如果我正确理解了你的问题,那么有距离的点并不是唯一的。它实际上是圆上以为中心和半径的所有点。CNBBN
0赞 Lori 12/31/2018
@Aziz,是的,你是对的。点 C 可以是该圆上的任何点。
0赞 Rory Daulton 12/31/2018
您对 3D 向量有足够的了解来实现我刚才在回答中给出的向量算法吗?
0赞 Lori 12/31/2018
@Rory,非常感谢您的回答。如果你能在代码中展示它是如何完成的,那将会很有帮助。

答:

1赞 Rory Daulton 12/31/2018 #1

如果所需的点 C 可以是符合您要求的无限多个点中的任何一个,则这里有一种方法。

选择任何与向量 AB 不平行或反平行的向量。你可以试试向量,如果它是平行的,你可以改用。然后取向量 AB 和所选向量的叉积。该叉积垂直于向量 AB,将该叉积除以其长度,然后乘以所需的长度 N。最后,从 B 点扩展该向量以找到所需的 C 点。(1, 0, 0)(0, 1, 0)

以下是遵循该算法的 Python 3 代码。这段代码在某种程度上是非pythonic的,以便更容易转换为其他语言。(如果我真的为自己做这件事,我会使用该模块来完全避免坐标并缩短此代码。但它确实将点视为 3 个值的元组:许多语言会要求您单独处理每个坐标。任何实际代码都需要检查“接近零”而不是“零”,并检查计算是否不会导致零。我将把这些额外的步骤留给你。如果您还有其他问题,请询问。numpysqrt

from math import sqrt

def pt_at_given_distance_from_line_segment_and_endpoint(a, b, dist):
    """Return a point c such that line segment bc is perpendicular to
    line segment ab and segment bc has length dist.

    a and b are tuples of length 3, dist is a positive float.
    """
    vec_ab = (b[0]-a[0], b[1]-a[1], b[2]-a[2])
    # Find a vector not parallel or antiparallel to vector ab
    if vec_ab[1] != 0 or vec_ab[2] != 0:
        vec = (1, 0, 0)
    else:
        vec = (0, 1, 0)
    # Find the cross product of the vectors
    cross = (vec_ab[1] * vec[2] - vec_ab[2] * vec[1],
             vec_ab[2] * vec[0] - vec_ab[0] * vec[2],
             vec_ab[0] * vec[1] - vec_ab[1] * vec[0])
    # Find the vector in the same direction with length dist
    factor = dist / sqrt(cross[0]**2 + cross[1]**2 + cross[2]**2)
    newvec = (factor * cross[0], factor * cross[1], factor * cross[2])
    # Find point c such that vector bc is that vector
    c = (b[0] + newvec[0], b[1] + newvec[1], b[2] + newvec[2])
    # Done!
    return c

命令的结果输出

print(pt_at_given_distance_from_line_segment_and_endpoint((1, 2, 3), (4, 5, 6), 2))

(4.0, 6.414213562373095, 4.585786437626905)

评论

0赞 Lori 12/31/2018
这是我的第一个问题,我很高兴能得到如此快速和精彩的答案!