如何在给定距离的任意垂直线上找到 3-D 中的点
How to find a point in 3-D at an arbitrary perpendicular line given distance to the point
我有一条AB线。我想画一条垂直于 AB 的线 BC。我知道点 A 和 B 的 xyz,我也知道 B 和 C 之间的距离 N。如何找到适合给定参数的任意点 C?计算应在 3-D 中进行。任何垂直于AB的点都可以是C点,如果它到B的距离等于N.
这里给出了一个几乎相同的问题,但我想知道同样的事情在 3-D 中是如何完成的:How do you find a point at a given perpendicular distance from a line?
上面 link 中给出了适用于我的二维计算:
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点不是唯一的。它可以是 圆 上的任意一点
中心在 B 和半径 N。 圆 垂直于 AB
如果你想要的点C可以是满足你要求的无限多个点中的任意一个,这里有一个方法。
选择任何不平行于或反平行于向量AB 的向量。您可以尝试向量 (1, 0, 0)
,如果它是平行的,您可以改用 (0, 1, 0)
。然后取向量 AB 和所选向量的叉积。该叉积垂直于向量 AB。将该叉积除以它的长度,然后乘以所需的长度 N。最后从 B 点扩展该向量以找到所需的 C 点。
这是 Python 3 中遵循该算法的代码。此代码有点非 pythonic,以便更容易转换为其他语言。 (如果我真的为自己这样做,我会使用 numpy
模块来完全避免坐标并缩短这段代码。)但它确实将点视为 3 个值的元组:许多语言将要求您分别处理每个坐标.任何现实生活中的代码都需要检查 "near zero" 而不是 "zero" 并检查 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)
我有一条AB线。我想画一条垂直于 AB 的线 BC。我知道点 A 和 B 的 xyz,我也知道 B 和 C 之间的距离 N。如何找到适合给定参数的任意点 C?计算应在 3-D 中进行。任何垂直于AB的点都可以是C点,如果它到B的距离等于N.
这里给出了一个几乎相同的问题,但我想知道同样的事情在 3-D 中是如何完成的:How do you find a point at a given perpendicular distance from a line?
上面 link 中给出了适用于我的二维计算:
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点不是唯一的。它可以是 圆 上的任意一点 中心在 B 和半径 N。 圆 垂直于 AB
如果你想要的点C可以是满足你要求的无限多个点中的任意一个,这里有一个方法。
选择任何不平行于或反平行于向量AB 的向量。您可以尝试向量 (1, 0, 0)
,如果它是平行的,您可以改用 (0, 1, 0)
。然后取向量 AB 和所选向量的叉积。该叉积垂直于向量 AB。将该叉积除以它的长度,然后乘以所需的长度 N。最后从 B 点扩展该向量以找到所需的 C 点。
这是 Python 3 中遵循该算法的代码。此代码有点非 pythonic,以便更容易转换为其他语言。 (如果我真的为自己这样做,我会使用 numpy
模块来完全避免坐标并缩短这段代码。)但它确实将点视为 3 个值的元组:许多语言将要求您分别处理每个坐标.任何现实生活中的代码都需要检查 "near zero" 而不是 "zero" 并检查 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)