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

时间:2018-12-30 21:03:15

标签: math graphics 3d geometry language-agnostic

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

这里给出了几乎相同的问题,但是我想知道在3-D中是如何完成相同的事情的:How do you find a point at a given perpendicular distance from a line?

在上面的链接中给出了适用于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-N * dz”之类的内容输入到C.z中,则该距离仅在某些旋转角度才是准确的,我想知道正确的解决方案。我可以想象在3-D中它是以完全不同的方式计算的。

说明

  • C点不是唯一的。它可以是 circle 上的任意点 中心位于B且半径为N。垂直于AB

1 个答案:

答案 0 :(得分:1)

如果所需点C可以是满足您要求的任意多个点,则这是一种方法。

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

这是Python 3中遵循该算法的代码。这段代码是非Python的,可以更轻松地转换为其他语言。 (如果我真的亲自做过此事,我将使用numpy模块来完全避免坐标并缩短此代码。)但是,确实会将点视为3值的元组:许多语言将要求您分别处理每个坐标。任何实际代码都需要检查“接近零”而不是“零”,并检查sqrt的计算结果是否为零。我将把这些其他步骤留给您。询问是否还有其他问题。

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)