CALayer旋转的投影

时间:2012-05-31 01:50:07

标签: 3d rotation calayer perspective

图层,frame {0,0,w,h}backgroundColor redanchorPoint at {0,0.5}transform.m34 = -1.0/1800, 并设置position at {0,0}, 然后沿着y CATransform3DRotate(layer.transform , 0.25 * M_PI, 0, 1, 0)以一个角度旋转它, 现在我想弄清楚红色区域的宽度。

一开始,我认为它应该是cos(0.25 * M_PI) *w, 然后我用代码测试它, 红色区域比cos(0.25 * M_PI) *w短,这应该是因为透视(物体越近,它看起来越大),但我不知道如何计算出红色区域的宽度。

1 个答案:

答案 0 :(得分:3)

如果我正确理解你,你要做的是确定一系列变换后两个不同点的相对位置。计算出这样做的方程式可能很棘手,我发现首先用矩阵编写所有内容然后通过自己乘以矩阵来得到方程式是有帮助的。

假设您的锚点位于原点,使用列主要矩阵(如open GL和CA Layer do)。 Position1代表矩形的左边缘,Position2代表右边缘。

Position1 = {1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            0,0,0,1};

Position2 ={1,0,0,w,  
            0,1,0,0,  
            0,0,1,0,  
            0,0,0,1};  

位置2现在需要围绕y轴旋转你的角度,所以我们声明

Rotation = {cos,0,sin,0,
              0,1,  0,0,
           -sin,0,cos,0,
              0,0,  0,1};

旋转需要应用于Position2,并且两者都需要乘以投影矩阵。 Position1不需要旋转,因为它位于旋转轴上。重要的是要认识到,将m34设置为一个小的负数并没有做任何魔术,你真正在做的是乘以投影矩阵

YourProjection = {1,0,0        ,0,
                  0,1,0        ,0,
                  0,0,1        ,0,
                  0,0,-1.0/1800,1};

乘以不同格式的投影矩阵同样适用,使用您最熟悉的任何内容。您可以使用Open GL之类的矩阵或you are using种类,因为它们确实是equivalent

Position2 = MultiplyMatrices(Rotation,Position2);
Position2 = MultiplyMatrices(YourProjection,Position2);
Position1 = MultiplyMatrices(YourProjection,Position1);

当CALayer对它们进行转换时,Position1和Position2现在保持它们的确切位置。由于它们是齐次坐标,因此必须确保将x,y,z分量(m41,42,43)除以w(m44)以转换回笛卡尔坐标。然后你需要做的就是获得宽度

float width = Position1.m41-Position2.m41;

如果你还没有,你应该自己制作矩阵乘法功能,这样你就可以快速轻松地进行这样的计算。你也不能因为代数错误这样混淆:)。如果你真的想以代数的方式做到这一点,那么只需要将它加倍,就可以得到你想要的东西。另外,如果我的矩阵表示法令人困惑,这里是从column major到CALayer变量的转换。

{m11,m12,m13,m14,
 m21,m22,m23,m24,
 m31,m32,m33,m34,
 m41,m42,m43,m44};

其中一个简单的翻译矩阵

{1,0,0,0,
 0,1,0,0,
 0,0,1,0,
 x,y,z,1};