python - 如何将平面 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?
解决方案
从文本中的定义(不阅读代码)来看,问题没有得到很好的定义 - 因为与给定向量正交的平面数量是无限的(将所有选项视为沿线的不同“偏移量”的平面第一点到第二点)。您需要首先选择飞机必须经过的某个点。
其次,当我们将 (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
推荐阅读
- python - 如何从数据框中的列中提取强标签并附加或替换该单元格?
- java - 为 Box 类创建测试驱动程序并测试其所有方法
- c# - 在功能区按钮查找中禁用 excel 构建 (FindDialogExcel)
- python - 从 windguru 刮桌子
- python - 如何在 matplotlib 的箱线图中删除自定义标签下的数字 x 刻度?
- java - 无法测试宁静的服务
- azure - 在开发 .NET 核心 Azure 功能时脱机使用 Azure 密钥库机密
- css - 为范围旋钮 ionic-range 添加边框颜色
- java - DDD - java 9 模块项目组织
- python - 将 Datetime 列转换为仅在 Python 中的 DataFrame 中显示日期