请忍受,因为我从未处理过与此相关的任何事情,并且在过去的两个星期我一直在处理此问题。
我正在开发一个程序,该程序可以从3D模型中读取人脸。通过在XYZ坐标中连接一系列3或4个顶点来绘制每个面。我的程序(或至少是意图)将遍历每个面部,将纹理图像映射到面部,然后保存图片。我可以处理后两个部分,但是将面部映射到2D曲面时遇到了麻烦。我无法使用常态,相信这会有所帮助。 (四边形的顶点始终位于同一平面上,因此四边形不会“弯曲”。)
到
我考虑过的潜在解决方案(但不知道如何实现):
代码答案可以接受,但不是必需的。 (VB,C#,JS,无论您喜欢什么),我也想知道我正在做的事情背后的数学原理。鼓励进行详尽的解释。
答案 0 :(得分:1)
一种方法是计算将脸部法线映射到(0, 0, 1)
的旋转。将该旋转应用于面部将使其位于xy平面中。
要计算脸部法线,请取任意三个点p1, p2, p3
并进行计算
n = normalize((p2 - p1) x (p3 - p1)),
其中x
是叉积。
然后,旋转轴为:
rotAxis = n x (0, 0, 1) = (ny, -nx, 0)
旋转角度为:
cos rotAngle = n * (0, 0, 1) = nz
sin rotAngle = sqrt(1 - nz * nz)
一旦有了此设置,就可以将旋转应用于脸部(例如,通过converting the rotation to a rotation matrix)。然后,只需放下z坐标即可。
最后,您还可以根据需要执行2D变换,例如平移和2D旋转。
答案 1 :(得分:1)
要获得一个面上的点的2D坐标,您需要在同一平面上两个正交的单位矢量。我们称它们为 u 和 v 。然后,对于平面中的每个3D点 p ,其2D坐标为(u.v,v.p),其中“。”。是点积。
首先计算表面法线。平面中任何两个向量的叉积都可以。您可能需要四处求和,将脸部各个角度的叉积相加,以平均出任何误差。将法线的长度标准化为1,并将其称为 n 。
现在,我们需要一个正交于法线的任意矢量。在 n 中选取坐标最小的轴,沿该轴制作单位矢量 x ,沿 n 移除其分量(即 x-= n *(xn)),并将其长度标准化为 u 。
然后只需取 n 和 u 的叉积即可得到 v 。