iOS實現3D旋轉

江楓夜雨發表於2017-04-02

最近看到了一個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); 

相關文章