想通了(这是问题的作者)。这只是一个错字,我没有计算飞机在正确方向上的法线......
这不像我说的那样(v0 X v1)它是偶然的(v1 X v0)。您可以在代码中看到它。所以,如果飞机是相反的方向,你就不能在上面投影。
因为这是一个愚蠢的错误。对于所有想知道平面上的矩阵投影背后的数学的人,我将尝试对其进行解释:
在开始之前,我假设对线性代数有一点粗略的了解。不需要太多。
假设我们有一个带有法线 N 的平面,上面有一个点 Q。对于每个点 P,当(且仅当)P 在平面上时,(P-Q).N=0(这是一个点积),因为向量 (P-Q) 和 N 是垂直的。
现在假设我们还有一个(固定聚光灯)点 S。我们想从那个聚光灯在我们的平面上投影一个点 P。这意味着我们希望找到点 R,它位于由点 P 和 S 定义的直线上的某处,并且也在平面上。换句话说,找到一个标量 t,使得S+t(P-S)=R,使得 R 在平面上。 (P-S) 是从聚光灯经过点 P 的方向向量。我们在该向量上“行走”一定量 t,从点 S 开始,直到我们降落在平面上。
从两段前,我们学到了一个很好的技巧来判断一个点是否在平面上。因此,如果我们在 R 上应用它,我们会得到 R 在平面上当(且仅当):
N.(R-Q)=0
N.R-N.Q=0
N.R=N.Q
N.(S+t(P-S))=N.Q
N.S+tN.(P-S)=N.Q
t=(N.Q-N.S)/(N.(P-S))
现在,如果我们把它放回 R 的定义中:
R=S+(N.Q-N.S)*(1/(N.(P-S))*(P-S)
让我们将N.(P-S)定义为k
kR=(N.(P-S))*S+(N.Q-N.S)*P-(N.Q-N.S)*S
kR=(N.P)*S+(N.Q-N.S)*P-(N.Q-N.S)*S-(N.S)*S
kR=(N.P)*S+(N.Q-N.S)*P-(N.Q)*S
让我们提醒自己我们知道什么,我们不知道什么,以及我们想知道什么。我们知道 N 和 Q 和 S。P 给了我们,我们想找到 R。换句话说,我们想表达 R 给定 P,并使用 N、Q 和 S。让我们继续分解一下进一步,
kR=(N_x*P_x+N_y*P_y+N_z*P_z)*S+(N.Q-N.S)*P-(N.Q)*S
R 是点,所以让我们用 P 的坐标来定义它的每一个坐标(还有 S,因为他也在等式的右边)。
kR_x=[N_x*S_x+(N.Q-N.S)]P_x+[N_y*S_x]P_y+[N_z*S_x]P_z-(N.Q)*S_x
kR_y=[N_x*S_y]P_x+[N_y*S_y+(N.Q-N.S)]P_y+[N_z*S_y]P_z-(N.Q)*S_y
kR_z=[N_x*S_z]P_x+[N_y*S_z]P_y+[N_z*S_z+(N.Q-N.S))]P_z-(N.Q)*S_z
看起来我们没有得到任何东西,因为我们得到了左边的 k,我们仍然需要除以它(而且 k 是由 P 定义的!)。不用担心,因为 OpenGL 使用四个元素向量而不是三个。最后第四个元素用于平移矩阵和透视深度插值。对于我们现在的需求,我们只需要知道 openGL 将每个顶点的坐标除以它的第四个元素。这意味着可怕的 k 是我们的第四个元素。我们得到:
R_w=k
R_w=N.(P-S)
R_w=N.P-N.S
R_w=[N_x]P_x+[N_y]P_y+[N_z]P_z-N.S
好的,我们通过 P 定义了我们的 R,使用 N、S 和 Q。让我们把它放在一个矩阵 M 中。我们想要:
M*P=R
所以,
M=
N_x*S_x + (N.Q-N.S), N_y*S_x, N_z*S_x, -(N.Q)*S_x
N_x*S_y, N_y*S_y + (N.Q-N.S), N_z*S_y, -(N.Q)*S_y
N_x*S_z, N_y*S_z, N_z*S_z + (N.Q-N.S), -(N.Q)*S_z
N_x, N_y, N_z, -(N.S)
看着这个,请记住,因为 P 是一个点,所以它的第四个元素是 1。(准确地说,!=0,但我们可以假设它是一个设备标准化顶点)
关于平面方程。平面方程是一个向量,它的前三个元素作为法线。它的第四个元素是它与原点的有符号距离。另一种计算平面到原点距离的方法是:
给定平面上的点Q,法线为N,平面到原点的距离为|N.Q|
很简单,对吧?这是正确的,因为:
N.Q=|N|*|Q|*cos(N,Q)
和|N|=1,给我们:
N.Q=|Q|*cos(N,Q)=|Q|*d/|Q|=d
其中 d 是从原点到平面的距离。或者,它是向量 N 的大小; N的大小是从原点到平面的距离的大小。您可以通过绘制平面,选择平面上的某个点 Q,绘制从原点延伸到平面的法线 N,并查看由两个向量和平面组成的线组成的三角形。
在上面的矩阵中,将 -N.Q 替换为 d(平面方程中的最后一个元素),就完成了。 (d = -N.Q)。给定点 P 的矩阵会将其从 S 定义的聚光灯投射到 N 和 Q 定义的平面上。
希望能教会你一些新的东西。如果我犯了错误,请发表评论,我会修复它。