首页 > 解决方案 > 如何将平面 uv 坐标中定义平面上的 2D 点转换回 3D xyz 坐标?

问题描述

我有一个已定义的平面(恰好与 3D 空间中的两个 xyz 点定义的向量正交)。我可以将任何 xyz 点投影到平面上并表示该投影 uv 坐标空间。我想在 uv 坐标空间中取一个任意点,并找出它在 xyz 空间中的坐标。

a = x2 - x1
b = y2 - y1
c = z2 - z1
d = -1*(a*x1 + b*y1 + c*z1)
magnitude = (a**2 + b**2 + c**2)**.5
u_magnitude = (b**2 + a**2)**.5

normal = [a/magnitude, b/magnitude, c/magnitude]
u = [b/u_magnitude, -a/u_magnitude, 0]
v = np.cross(normal, u)

p_u = np.dot(u,[x1,y1,z1])
p_v = np.dot(v,[x1,y1,z1])

我相信这段代码可以准确地生成我想要的平面,并将 uv 坐标中的 x1,y1,z1 点分配给 p_u,p_v。我的感觉是我拥有执行反向操作所需的一切,但我不知道如何操作。如果我有一个点 u0,v0 我怎样才能找到描述其在 3D 空间中的位置的 x0,y0,z0?

标签: pythonmath3dcoordinate-systemsplane

解决方案


从文本中的定义(不阅读代码)来看,问题没有得到很好的定义 - 因为与给定向量正交的平面数量是无限的(将所有选项视为沿线的不同“偏移量”的平面第一点到第二点)。您需要首先选择飞机必须经过的某个点。

其次,当我们将 (U, V) 对转换为 3D 点时,我假设您的意思是平面上的 3D 点。

不过,试图更具体一点,这是您的代码,其中包含有关我如何理解它的文档,以及如何进行相反的操作:

# ### The original computation of the plane equation ###
# Given points p1 and p2, the vector through them is W = (p2 - p1)
# We want the plane equation Ax + By + Cz + d = 0, and to make
# the plane prepandicular to the vector, we set (A, B, C) = W
p1 = np.array([x1, y1, z1])
p2 = np.array([x2, y2, z2])

A, B, C = W = p2 - p1

# Now we can solve D in the plane equation. This solution assumes that
# the plane goes through p1.
D = -1 * np.dot(W, p1)

# ### Normalizing W ###
magnitude = np.linalg.norm(W)
normal = W / magnitude

# Now that we have the plane, we want to define
# three things:
# 1. The reference point in the plane (the "origin"). Given the
#    above computation of D, that is p1.
# 2. The vectors U and V that are prepandicular to W
#    (and therefore spanning the plane)

# We take a vector U that we know that is perpendicular to
# W, but we also need to make sure it's not zero.
if A != 0:
    u_not_normalized = np.array([B, -A, 0])
else:
    # If A is 0, then either B or C have to be nonzero
    u_not_normalized = np.array([0, B, -C])
u_magnitude = np.linalg.norm(u_not_normalized)

# ### Normalizing W ###
U = u_not_normalized / u_magnitude
V = np.cross(normal, U)

# Now, for a point p3 = (x3, y3, z3) it's (u, v) coordinates would be
# computed relative to our reference point (p1)
p3 = np.array([x3, y3, z3])

p3_u = np.dot(U, p3 - p1)
p3_v = np.dot(V, p3 - p1)

# And to convert the point back to 3D, we just use the same reference point
# and multiply U and V by the coordinates
p3_again = p1 + p3_u * U + p3_v * V

推荐阅读