iOS動畫 三維透視投影 m34

transform的結構以下:
struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};

首先要實現view(layer)的透視效果(就是近大遠小),是經過設置m34的:

CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;

m34負責z軸方向的translation(移動),m34= -1/D,  默認值是0,也就是說D無窮大,這意味layer in projection plane(投射面)和layer in world coordinate重合了。

D越小透視效果越明顯。

html

所謂的D,是eye(觀察者)到投射面的距離。app

 

 

 

 概述框架

 

在iOS中使用CATransform3D這個結構體來表示三維的齊次座標變換矩陣. 齊次座標是一種座標的表示方法,n維空間的座標須要用n+1個元素的座標元組來表示,在Quartz 2D Transform中就有關於齊次座標的應用,那邊是關於二維空間的變換,其某點的齊次座標的最後一個元素始終設置爲1。使用齊次座標而不是簡單的數學座標是爲了方便圖形進行仿射變換,仿射變換能夠經過仿射變換矩陣來實現,3D的仿射變換能夠實現諸如 平移(translation),旋轉(rotation),縮放(scaling),切變(shear)等變換。若是不用齊次座標那麼進行座標變換可能就涉及到兩種運算了,加法(平移)和乘法(旋轉,縮放),而使用齊次座標以及齊次座標變換矩陣後只須要矩陣乘法就能夠完成一切了。上面的這些若是須要深刻了解就須要去學習一下圖形變換的相關知識,本身對矩陣的乘法進行演算。函數

iOS中的CALayer的3D本質上並不能算真正的3D(其視點即觀察點或者所謂的照相機的位置是沒法變換的),而只是3D在二維平面上的投影,投影平面就是手機屏幕也就是xy軸組成的平面(注意iOS中爲左手座標系),那麼視點的位置是如何肯定的呢?能夠經過CATransform3D中的m34來間接指定, m34 = -1/z,其中z爲觀察點在z軸上的值,而Layer的z軸的位置則是經過anchorPoint來指定的,所謂的anchorPoint(錨點)就是在變換中保持不變的點,也就是某個Layer在變換中的原點,xyz三軸相交於此點。在iOS中,Layer的anchorPoint使用unit coordinate space來描述,unit coordinate space無需指定具體真實的座標點而是使用layer bounds中的相對位置,下圖展現了一個Layer中的幾個特殊的錨點, 
學習

m34 = -1/z中,當z爲正的時候,是咱們人眼觀察現實世界的效果,即在投影平面上表現出近大遠小的效果,z越靠近原點則這種效果越明顯,越遠離原點則愈來愈不明顯,當z爲正無窮大的時候,則失去了近大遠小的效果,此時投影線垂直於投影平面,也就是視點在無窮遠處,CATransform3D中m34的默認值爲0,即視點在無窮遠處.ui

還有一個須要說明一下的就是齊次座標到數學座標的轉換 通用的齊次座標爲 (a, b, c, h),其轉換成數學座標則爲 (a/h, b/h, c/h).spa

代數解釋

假設一個Layer anchorPoint爲默認的 (0.5, 0.5 ), 其三維空間中一個A點 (6, 0, 0),m34 = -1/1000.0, 則此點往z軸負方向移動10個單位以後,則在投影平面上看到的點的座標是多少呢?code

A點使用齊次座標表示爲 (6, 0, 0, 1)orm

QuartzCore框架爲咱們提供了函數來算出所須要的矩陣,htm

CATransform3D transform = CATransform3DIdentity; transform.m34 = -1/1000.0; transform = CATransform3DTranslate(transform, 0, 0, -10); 

計算出來的矩陣爲

{ 1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, -0.001; 0, 0, -10, 1.01; } 

其實上面的變換矩陣本質上是兩個矩陣相乘獲得的 變換矩陣 * 投影矩陣 變換矩陣爲

{1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, -10, 1; } 

投影矩陣爲

{1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, -0.001; 0, 0, 0, 1; } 

上面的兩個矩陣相乘則會獲得最終的變換矩陣(若是忘記矩陣乘法的能夠去看下線性代數複習下),因此一個矩陣就能夠完成變換和投影。

將A點座標乘上最終的變換矩陣,則獲得 {6, 0 , -10, 1.01}, 轉換成數學座標點爲 {6/1.01, 0, 10/1.01},則能夠知道其在投影平面上的投影點爲 {6/1.01, 0, 0} 也就是咱們看到的變換後的點。其比以前較靠近原點。越往z軸負方向移動,則在投影平面上越靠近原點。

 

幾何解釋

將上面的例子使用幾何的方式來進行解釋分析,當咱們沿着y軸的正方向向下看時候,能夠獲得以下的景象

虛線爲投影線,其和x軸的交點即爲A點的投影點。 由類似三角形的定理咱們很容易算出投影的點,

1000/(1000 + 10) = x/6,則x = 6*1000/1010 = 6/1.01

相關文章
相關標籤/搜索