iOS实现3D旋转

来源:互联网 发布:清华计算机系课程知乎 编辑:程序博客网 时间:2024/05/03 15:04

最近看到了一个3D旋转的动画,就想着自己去实现以下。那么,接下来就通过这边文章记录以下学习过程,慢慢深入了解以下3D旋转。

一、如何旋转

每个View都在系统的坐标系中,就手机屏幕来说,左上角为 (0 , 0),向右横向的为X轴正方向,向下纵向的为Y轴正方向,垂直于手机屏幕的方向既Z轴方向。
这里写图片描述

所以Z轴的旋转属于平面上的旋转,实现3D效果的前提就是有X轴或者Y轴的参与。

二、沿着Y轴旋转

先看一下CATransform3DMakeRotation的定义:CA_EXTERN CATransform3D CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z)angle:角度    x,y,z分别代表是三个方向的坐标

按照这个思路,于是我写下如下的代码:

CATransform3D rotate = CATransform3DMakeRotation(M_PI/6, 0, 1, 0);self.imageView.layer.transform = rotate;

运行之后可以发现,imageView 并没有出现3D效果,只是单纯的在Y轴缩短了一些。为何会出现这样的效果?

查资料后发现,原来在CALayer的显示系统中,默认使用的是正交投影,没有远小近大效果,所以我们对 imageView 的旋转操作,只能造成Y轴上的缩放。而无法观察到3D 的效果。

其实这个时候 imageView 已经沿着Y轴旋转了 M_PI/6 ,但只是我们无法直接观察到这种效果。

三、添加3D效果

这时候我们需要用到透视投影。

先看每个矩阵里数字代表的含义:

 struct CATransform3D { CGFloat m11(x缩放), m12(y切变), m13(旋转), m14(); CGFloat m21(x切变), m22(y缩放), m23(), m24(); CGFloat m31(旋转), m32(), m33(), m34(透视效果); CGFloat m41(x平移), m42(y平移), m43(z平移), m44(); };我们所需要的正是 m34 。

构造一个旋转矩阵

CATransform3D rotate = CATransform3DMakeRotation(M_PI/6, 0, 1, 0);

构造一个透视矩阵

其中:M34属性 控制透视效果

正的值向下(左)方往里缩放 负的值上(右)方往里缩放

disZ 控制透视的强度 数字越小 深度越大 拉伸效果越明显

CGFloat disZ = 200;CATransform3D scale = CATransform3DIdentity;scale.m34 = -1.0f/disZ; 

然后把两个矩阵相乘 旋转矩阵*透视矩阵

CATransform3D transform = CATransform3DConcat(rotate, scale);    

把最后的结果赋给 imageView 的 layer 的 transform 。

self.imageView.layer.transform = transform;

运行起来,具有3D效果的一张图就展示在我们的眼前了,啧啧,是不是挺简单。

四、控制旋转中心轴

如果通过角度的递增,给我们的3D旋转加一个动画,我们就会明显的看到,默认的以平行于Y轴的 imageView 的中心轴进行旋转。那么如果让我们 imageView 以自己的左边线进行旋转呢?

其实也很简单,旋转是以layer的锚点为中心进行旋转的。默认是 (0.5 , 0.5) 。我们只需要改变锚点的位置就好了。

image.layer.anchorPoint = CGPointMake(0, 0.5); 
0 0
原创粉丝点击