4

以下代码可以对图层进行透视旋转变换:

CATransform3D transform3DFoo = CATransform3DIdentity;

transform3DFoo.m34 = -1.0 / 1000;

transform3DFoo = CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0);

但是,如果两行颠倒:

CATransform3D transform3DFoo = CATransform3DIdentity;

transform3DFoo = CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0);

transform3DFoo.m34 = -1.0 / 1000;

然后视角消失了。现在它是正交的(没有透视)。熟悉透视的人知道原因吗?


更新:

// First Identity and then transform3DFoo.m34 = -1.0 / 1000; is done

1.00000     0.00000     0.00000     0.00000 
0.00000     1.00000     0.00000     0.00000 
0.00000     0.00000     1.00000    -0.00100 
0.00000     0.00000     0.00000     1.00000 

// and then CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0);

1.00000     0.00000     0.00000     0.00000 
0.00000     0.70711     0.70711    -0.00071 
0.00000    -0.70711     0.70711    -0.00071 
0.00000     0.00000     0.00000     1.00000 

// Now start with Identity and only the Rotate statement is done:

1.00000     0.00000     0.00000     0.00000 
0.00000     0.70711     0.70711     0.00000 
0.00000    -0.70711     0.70711     0.00000 
0.00000     0.00000     0.00000     1.00000 

// and then transform3DFoo.m34 = -1.0 / 1000; is done

1.00000     0.00000     0.00000     0.00000 
0.00000     0.70711     0.70711     0.00000 
0.00000    -0.70711     0.70711    -0.00100 
0.00000     0.00000     0.00000     1.00000 

(加上“OpenGL”的标签是因为在OpenGL中应该是一样的原理)

4

1 回答 1

6

先设置m34相当于先旋转后投影。最后设置m34大致相当于先投影后旋转。由于输入坐标的 z=0,首先投影不会做任何事情。

要了解这是为什么,您需要了解一下变换矩阵的工作原理。

我相信在 CA 位置是由一个变换矩阵M通过执行以下操作进行变换的:

[x y z w] = [x y z w] * M

(见http://en.wikipedia.org/wiki/Matrix_multiplication

将两个变换矩阵相乘相当于连接变换。左边的变换/矩阵首先发生。很容易看出这是为什么:

[x y z w] * (LEFT * RIGHT) = ([x y z w] * LEFT) * RIGHT

大多数(全部?)CA变换函数(例如CATransform3DRotate)只是将您的变换矩阵与另一个适当构造的矩阵预乘,例如:

M = ROTATE * M

设置m34大致相当于预乘一个投影矩阵,即:

M = PROJ * M

PROJ投影矩阵在哪里——一个单位矩阵,但有m34集合)

这并不完全正确(这就是我一直粗略地说的原因)——它只有M在正确的位置有一些 0 和 1 时才有效。基本上,在一般情况下,只是设置m34是一件无意义的事情——正确的做法是乘以一个投影矩阵。

无论如何,如果你把所有这些放在一起,你应该能够明白为什么我在第一段中所说的是真的(假设我没有犯任何错误:)

于 2012-06-08T01:22:58.090 回答