简体   繁体   English

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

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

I have a line AB.我有一条AB线。 I would like to draw a line BC, perpendicular to AB.我想画一条线BC,垂直于AB。 I know xyz of the points A and B, I also know the distance N between B and C. How can I find an arbitrary point C which fits into the given parameters?我知道 A 和 B 点的 xyz,我也知道 B 和 C 之间的距离 N。如何找到适合给定参数的任意点 C? The calculations should be done in 3-D.计算应在 3-D 中完成。 Any point, perpendicular to AB can be the point C, if its distance to B equals N.任何垂直于 AB 的点都可以是点 C,如果它到 B 的距离等于 N。

An almost identical question is given here, but I would like to know how the same thing is done in 3-D: How do you find a point at a given perpendicular distance from a line?这里给出了一个几乎相同的问题,但我想知道如何在 3-D 中完成同样的事情: 如何找到距直线给定垂直距离处的点?

The calculation that works for me in 2-D was given in the link above:上面的链接中给出了在二维中对我有用的计算:

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

I tried adding Z axis to it like this:我尝试像这样向它添加 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

If I put something like "Cz - N*dz" into Cz, the distance is accurate only in some rotation angles, I would like to know the correct solution.如果我将“Cz - N * dz”之类的东西放入Cz,则距离仅在某些旋转角度上是准确的,我想知道正确的解决方案。 I can imagine that in 3-D it is calculated in a completely different manner.我可以想象在 3-D 中它是以完全不同的方式计算的。

Clarification澄清

  • Point C is not unique. C点不是唯一的。 It can be any point on a circle with its centre at B and radius N. The circle is perpendicular to AB它可以是与它的在B和半径N.圆心的任何点是垂直于AB

If the desired point C can be any of the infinitely-many points fitting your requirements, here is one method.如果所需的点 C 可以是符合您要求的无限多点中的任何一个,这里是一种方法。

Choose any vector that is not parallel or anti-parallel to vector AB.选择与向量 AB 不平行或反平行的任何向量。 You could try the vector (1, 0, 0) , and if that is parallel you could use (0, 1, 0) instead.您可以尝试使用向量(1, 0, 0) ,如果它是并行的,您可以使用(0, 1, 0)代替。 Then take the cross-product of vector AB and the chosen vector.然后取向量 AB 和所选向量的叉积。 That cross-product is perpendicular to vector AB.该叉积垂直于向量 AB。 Divide that cross-product by its length then multiply by the desired length N. Finally extend that vector from point B to find your desired point C.将该叉积除以其长度,然后乘以所需的长度 N。 最后从 B 点扩展该向量以找到所需的 C 点。

Here is code in Python 3 that follows that algorithm.这是遵循该算法的 Python 3 代码。 This code is somewhat non-pythonic to make it easier to convert to other languages.这段代码有点非pythonic,以便更容易转换为其他语言。 (If I really did this for myself I would use the numpy module to avoid coordinates completely and shorten this code.) But it does treat the points as tuples of 3 values: many languages will require you to handle each coordinate separately. (如果我真的为自己这样做,我会使用numpy模块来完全避免坐标并缩短此代码。)但它确实将点视为 3 个值的元组:许多语言将要求您分别处理每个坐标。 Any real-life code would need to check for "near zero" rather than "zero" and to check that the sqrt calculation does not result in zero.任何现实生活中的代码都需要检查“接近零”而不是“零”,并检查sqrt计算结果是否为零。 I'll leave those additional steps to you.我会把这些额外的步骤留给你。 Ask if you have more questions.询问您是否有更多问题。

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

The resulting output from the command命令的结果输出

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

is

(4.0, 6.414213562373095, 4.585786437626905)

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

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