用3D顶点绘制2D面

时间:2019-04-24 02:16:27

标签: math rotation trigonometry face

请忍受,因为我从未处理过与此相关的任何事情,并且在过去的两个星期我一直在处理此问题。

我正在开发一个程序,该程序可以从3D模型中读取人脸。通过在XYZ坐标中连接一系列3或4个顶点来绘制每个面。我的程序(或至少是意图)将遍历每个面部,将纹理图像映射到面部,然后保存图片。我可以处理后两个部分,但是将面部映射到2D曲面时遇到了麻烦。我无法使用常态,相信这会有所帮助。 (四边形的顶点始终位于同一平面上,因此四边形不会“弯曲”。)

Face in 3D space

Face in 2D space

我考虑过的潜在解决方案(但不知道如何实现):

  1. 使用2个顶点,计算与轴的角度偏差(例如,使用四边形的顶部2个顶点来计算旋转Y)。 Using delta X and delta Y to calculate rotation Y对所有三个轴都进行此操作之后,我可以将顶点反向旋转,以希望使其变平(我不知道该怎么做)。但是,我看到的这个解决方案的问题是,x坐标可以改变2圈(y和z),而不仅仅是1圈(y和z坐标也一样)。
  2. 我没有旋转面部,而是重新创建了形状。像解决方案1中一样,我使用两个顶点。我不计算旋转,而是计算ege的长度和斜率。然后,我可以在2D空间中绘制同一条线,并重复其他边缘。我找到了边缘的斜率,这样我就可以正确确定相交边缘的角度(考虑极坐标)。我对如何执行此操作有一个想法,但是我不确定这是最佳解决方案。
我猜是

代码答案可以接受,但不是必需的。 (VB,C#,JS,无论您喜欢什么),我也想知道我正在做的事情背后的数学原理。鼓励进行详尽的解释。

2 个答案:

答案 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