flutter佈局-5-Matrix4矩陣變換

劉成發表於2018-11-07

Matrix4矩陣變化

連載:flutter佈局-1-column 連載:flutter佈局-2-row 連載:flutter佈局-3-center 連載:flutter佈局-4-container

這個是用來變換的矩陣,總計需要16個引數也可以理解成4*4的矩陣。 具體有以下引數:

scale:縮放比例
transform: 移動
rotationZ:繞Z軸旋轉
rotationX:繞X軸旋轉
rotationY:繞Y軸旋轉
columns:設定一個新的矩陣
compose:複合平移、旋轉、縮放,形成新的狀態
copy:複製一個4*4的張量(矩陣)

複製程式碼

4*4矩陣:

Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
複製程式碼

1、scale:縮放比例 transform: Matrix4.diagonal3Values(2, 10, 1),

縮放.png

Matrix4.diagonal3Values(1, 1, 1) 表示縮放的比例,分別沿x,y,z三個方向,x軸正向向右,y軸正向向下,z軸正向從螢幕朝上,正值表示正向,>1表示放大,小於1大於0表示縮小,負值表示反向。

scale.png

上面的值紅框的寬高都是80,裡面的小框寬高都是30,縮放的時間這樣更能體現兩個的相對位置。 具體的使用方法或者值,大家可以仔細看下上面的圖片。 Z軸的變化在平面手機上看不出效果,後面我們在做旋轉的時間可以具體看下z軸的變化。

縮放有以下幾種寫法: 舉個例子:向x軸正向放大2倍。

  1. Matrix4.diagonal3Values(2, 1, 1)
  2. Matrix4.diagonal3(v.Vector3(2, 1, 1))
  3. Matrix4.diagonal3(v.Vector3.array([2, 1, 1]))
  4. Matrix4(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) 上述三種寫法都表示向x軸正方向移動30個單位距離。 第2、3兩中寫法是用三維向量表示的,但是需要匯入向量包 import 'package:vector_math/vector_math_64.dart' as v; 第4中寫法是4*4的矩陣寫法: 其中矩陣的第1、6、11個值分別代表的是x軸縮放、y軸縮放、z軸縮放

2、transform: 移動

transform.png

表示平移的距離,分別沿x,y,z三個方向, x軸正向向右, y軸正向向下, z軸正向從螢幕朝上, 正值表示正向移動,負值表示負向移動, 其中z軸移動在平面上無法看出小錯

移動有以下幾種寫法: 舉個例子:向右移動30個單位的距離。

  1. Matrix4.translationValues(30, 0, 0)
  2. Matrix4.translation(v.Vector3(30, 0, 0))
  3. Matrix4.translation(v.Vector3.array([0, -30, 0]))
  4. Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30, 0, 0, 1) 上述三種寫法都表示向x軸正方向移動30個單位距離。 第2、3兩中寫法是用三維向量表示的,但是需要匯入向量包 import 'package:vector_math/vector_math_64.dart' as v; 第4中寫法是4*4的矩陣寫法: 其中矩陣的第13、14、15個值分別代表的是x軸平移、y軸平移、z軸平移

3、rotationZ:繞Z軸旋轉

rotationZ.png

繞著Z軸旋轉,正向是順時針,負向是逆時針, 正向也就是從x軸正向往y軸正向旋轉

兩種寫法:

  1. Matrix4.rotationZ(pi / 6) , 引數是弧度
  2. Matrix4(cos(pi / 6), sin(pi / 6), 0, 0,-sin(pi / 6), cos(pi / 6), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) , 引數是弧度。 也就是改變 1、2、5、6這個4個值 其中1、6的值相同,為cos值 2、5相反,2位sin值,5為-sin值

4、rotationX:繞X軸旋轉

rotationX.png

繞著X軸旋轉,正向是順時針,負向是逆時針, 正向也就是從y軸正向往z軸正向旋轉

兩種寫法:

  1. Matrix4.rotationX(pi / 6) , 引數是弧度
  2. Matrix4(1, 0, 0, 0, 0, cos(pi / 6), sin(pi / 6), 0, 0, -sin(pi / 6), cos(pi / 6), 0, 0, 0, 0, 1) , 引數是弧度。 也就是改變 6、7、10、11這個4個值 矩陣的6 cos(pi/6), 7的值 sin(pi/6), 10的值 -sin(pi/6), 11的值 cos(pi/6)

5、rotationY:繞Y軸旋轉

rotationY.png
上圖的右下角座標系表示:

左側灰色大小是原形狀
藍色是繞Y軸旋轉30°的形狀
紅色虛線是投影虛線

紅色實線是旋轉後在xy平面
也就是手機螢幕上的投影

0-90 正向旋轉角度越大,最終在手機上的投影越小,90°的時間就是一條線,而線的點是無限小的,肉眼是看不到的,所以會出現90°沒有東西存在的情況。
如果想看90°的效果,就把角度改成 178*pi/180,就會出現一條線
複製程式碼

繞著Y軸旋轉,正向是順時針,負向是逆時針, 正向也就是從x軸正向往z軸正向旋轉

兩種寫法:

  1. Matrix4.rotationY(pi / 6) , 引數是弧度
  2. Matrix4(cos(pi / 6), 0, -sin(pi / 6), 0, 0, 1, 0, 0, sin(pi / 6), 0, cos(pi / 6), 0, 0, 0, 0, 1) , 引數是弧度。 也就是改變 1、3、9、11這個4個值 矩陣的1 cos(pi/6), 3的值 -sin(pi/6), 9的值 sin(pi/6), 11的值 cos(pi/6)

6、columns:設定一個新的矩陣

 Matrix4.columns(
                        v.Vector4(1, 0, 0, 0),
                        v.Vector4(0, 1, 0, 0),
                        v.Vector4(0, 0, 1, 0),
                        v.Vector4(0, 0, 0, 1)) 
複製程式碼

需要匯入 import 'package:vector_math/vector_math_64.dart' as v;

4個引數都是一個4維的向量,也就是一個4個值的一維陣列. 跟直接設定 Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)是一樣的效果

7、compose:複合平移、旋轉、縮放,形成新的狀態

Matrix4.columns( 
Vector3 translation, 
Quaternion rotation, 
Vector3 scale) 
複製程式碼

第一個平移引數是三維向量:v.Vector3(30,0,0),表示向右移動30個單位的距離,影響的是矩陣的13,14,15三個數值; 第二個引數是4維向量,在旋轉裡面也可以叫四元數,進行旋轉的計算,四元數和尤拉角可以相互轉換,影響矩陣的引數有 1、2、3、5、6、7、9、10、11,也就是說這幾個引數是影響旋轉的。 從上面的旋轉rotationxyz可以看出:

x軸旋轉影響的引數是 6、7、10、11 y軸旋轉影響的引數是 1、3、9、11 z軸旋轉影響的引數是 1、2、5、6

第三個引數是一個三維向量:進行縮放的,影響矩陣的 1、6、11

所以縮放是和旋轉相關的,從上面旋轉的圖片結果可以看出,

計算的方法是先拿平移的引數和旋轉的四元素進行計算,然後在進行縮放

8、copy:複製一個4*4的張量(矩陣)

Matrix4.copy( Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) )
複製程式碼

9、identity:恢復初始狀態,也就是4*4的單位矩陣

Matrix4.identity()
複製程式碼

10、inverted:取相反的矩陣,就是反著來

你要往東,結果就往西

Matrix4.inverted(Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 30, 0, 1))
裡面的矩陣表示y軸向下移動30個單位距離
取反後是沿著y軸向上30個單位距離
複製程式碼
Matrix4.inverted(Matrix4(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))
裡面的矩陣表示 x軸 放大兩倍,也就是所有的座標都*2 
取反後是沿著x軸縮小1倍,也就是所有的座標*0.5

複製程式碼

其中6,7,8,9,10的示例如下:

columns_compose_identity_inverted_copy.png

11、outer(合併)、skew(扭曲)、skewX(x軸扭曲)、skewY(y軸扭曲)、zero(置零矩陣)、fromList(將一個16位的一維陣列轉換成4*4的矩陣)

outer.png

 * outer 兩個4維向量的乘積合併
 * skew:扭曲
 * skewX:沿著x軸扭曲
 * skewY:沿著y軸扭曲
 * zero: 全是0的4*4的張量
 * fromList: 將一個16位的一維陣列轉換成4*4的矩陣
複製程式碼

相關文章