構造方法
Matrix ()
Matrix (Matrix src)
基本方法
-
equals()
:比較兩個Matrix
的數值是否相同。 -
hashCode()
:獲取Matrix
的哈希值。 -
toString()
:將Matrix
轉換為字符串:Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
。 -
toShortString()
:將Matrix
轉換為短字符串:[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]
。
數值操作
set
沒有返回值,有一個參數,作用是將參數Matrix
的數值復制到當前Matrix
中。如果參數為空,則重置當前Matrix
,相當于reset()
。
void set (Matrix src)
reset
重置當前Matrix
(將當前Matrix
重置為單位矩陣)。
void reset ()
setValues
setValues()
的參數是浮點型的一維數組,長度需要大于9,拷貝數組中的前9位數值賦值給當前Matrix
。
void setValues(float[] values)
getValues
參數是浮點型的一維數組,長度需要大于9,將Matrix
中的數值拷貝進參數的前9位中。
void getValues(float[] values)
數值計算
mapPoints
計算一組點基于當前Matrix
變換后的位置,(由于是計算點,所以參數中的float數組長度一般都是偶數的,若為奇數,則最后一個數值不參與計算)。
void mapPoints(float[] pts)
void mapPoints(float[] dst, float[] src)
void mapPoints(float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)
方法一
void mapPoints (float[] pts)
方法僅有一個參數,pts
數組作為參數傳遞原始數值,計算結果仍存放在pts
中。
方法二
void mapPoints (float[] dst, float[] src)
,src
作為參數傳遞原始數值,計算結果存放在dst
中,src
不變。
方法三
void mapPoints (float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)
可以指定只計算一部分數值。
參數 | 摘要 |
---|---|
dst | 目標數據 |
dstIndex | 目標數據存儲位置起始下標 |
src | 源數據 |
srcIndex | 源數據存儲位置起始下標 |
pointCount | 計算的點個數 |
mapRadius
測量半徑,由于圓可能會因為畫布變換變成橢圓,所以此處測量的是平均半徑。
方法
float mapRadius(float radius)
示例
float radius = 100;
float result = 0;
// 構造一個matrix,x坐標縮放0.5
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 1f);
Log.i(TAG, "mapRadius: "+radius);
result = matrix.mapRadius(radius);
Log.i(TAG, "mapRadius: "+result);
mapRadius: 100.0
mapRadius: 70.71068
mapRect
測量矩形變換后位置,返回值是判斷矩形經過變換后是否仍為矩形,非90度倍數的旋轉也會變成非矩形。
boolean mapRect(RectF rect)
boolean mapRect(RectF dst, RectF src)
方法一
boolean mapRect (RectF rect)
測量rect
并將測量結果放入rect
中。
方法二
boolean mapRect (RectF dst, RectF src)
測量src
并將測量結果放入dst
中。
mapVectors
測量向量,mapVectors
與 mapPoints
基本上是相同的,可以直接參照上面的mapPoints
使用方法。兩者唯一的區別就是mapVectors
不會受到位移的影響,這符合向量的定律。
void mapVectors(float[] vecs)
void mapVectors(float[] dst, float[] src)
void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)
set、pre 與 post
方法 | 簡介 |
---|---|
set | 設置,會覆蓋掉之前的數值,導致之前的操作失效。 |
pre | 前乘,構造矩陣乘式時,往前端壓入乘式因子。 |
post | 后乘,構造矩陣乘式時,往后端壓入乘式因子。 |
特殊方法
setPolyToPoly
簡介
Poly 全稱是 Polygon ,多邊形的意思。setPolyToPoly()
最多可以支持4個點。
boolean setPolyToPoly (
float[] src, // 原始數組 src [x,y],存儲內容為一組點
int srcIndex, // 原始數組開始位置
float[] dst, // 目標數組 dst [x,y],存儲內容為一組點
int dstIndex, // 目標數組開始位置
int pointCount) // 測控點的數量 取值范圍是: 0到4
pointCount | 摘要 |
---|---|
0 | 相當于reset
|
1 | 可以進行 平移 |
2 | 可以進行 縮放、旋轉、平移 變換 |
3 | 可以進行 縮放、旋轉、平移、錯切 變換 |
4 | 可以進行 縮放、旋轉、平移、錯切以及任何形變 |
示例
public class MatrixSetPolyToPolyTest extends View {
private Bitmap mBitmap; // 要繪制的圖片
private Matrix mPolyMatrix; // 測試setPolyToPoly用的Matrix
public MatrixSetPolyToPolyTest(Context context) {
super(context);
initBitmapAndMatrix();
}
private void initBitmapAndMatrix() {
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.poly_test);
mPolyMatrix = new Matrix();
float[] src = {0, 0, // 左上
mBitmap.getWidth(), 0, // 右上
mBitmap.getWidth(), mBitmap.getHeight(), // 右下
0, mBitmap.getHeight()}; // 左下
float[] dst = {0, 0, // 左上
mBitmap.getWidth(), 400, // 右上
mBitmap.getWidth(), mBitmap.getHeight() - 200, // 右下
0, mBitmap.getHeight()}; // 左下
// 核心要點
mPolyMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); // src.length >> 1 為位移運算 相當于處以2
// 此處為了更好的顯示對圖片進行了等比縮放和平移(圖片本身有點大)
mPolyMatrix.postScale(0.26f, 0.26f);
mPolyMatrix.postTranslate(0,200);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 根據Matrix繪制一個變換后的圖片
canvas.drawBitmap(mBitmap, mPolyMatrix, null);
}
}
pointCount為0
pointCount()
為0
和reset()
是等價的。
pointCount為1
pointCount()
為1
和translate
是等價的,平移的距離是dst - src
。
pointCount為2
當pointCount
為2
的時候,可以做縮放、平移和旋轉。
pointCount為3
當pointCount
為3
的時候,可以做縮放、平移、旋轉和錯切。
pointCount為4
當pointCount
為4
的時候,你可以將圖像拉伸為任意四邊形。
setRectToRect
簡介
將源矩形的內容填充到目標矩形中。
boolean setRectToRect (RectF src, // 源區域
RectF dst, // 目標區域
Matrix.ScaleToFit stf) // 縮放適配模式
Matrix.ScaleToFit
:
模式 | 摘要 |
---|---|
CENTER | 居中,對src等比例縮放,將其居中放置在dst中。 |
START | 頂部,對src等比例縮放,將其放置在dst的左上角。 |
END | 底部,對src等比例縮放,將其放置在dst的右下角。 |
FILL | 充滿,拉伸src的寬和高,使其完全填充滿dst。 |
圖示
src(原始狀態) | |
---|---|
CENTER | |
START | |
END | |
FILL |
示例
展示居中例子:
public class MatrixSetRectToRectTest extends View {
private static final String TAG = "MatrixSetRectToRectTest";
private int mViewWidth, mViewHeight;
private Bitmap mBitmap; // 要繪制的圖片
private Matrix mRectMatrix; // 測試etRectToRect用的Matrix
public MatrixSetRectToRectTest(Context context) {
super(context);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rect_test);
mRectMatrix = new Matrix();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mViewWidth = w;
mViewHeight = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF src= new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight() );
RectF dst = new RectF(0, 0, mViewWidth, mViewHeight );
// 核心要點
mRectMatrix.setRectToRect(src,dst, Matrix.ScaleToFit.CENTER);
// 根據Matrix繪制一個變換后的圖片
canvas.drawBitmap(mBitmap, mRectMatrix, new Paint());
}
}
rectStaysRect
判斷矩形經過變換后是否仍為矩形,假如Matrix
進行了平移、縮放則畫布僅僅是位置和大小改變,矩形變換后仍然為矩形,但Matrix
進行了非90度倍數的旋轉或者錯切,則矩形變換后就不再是矩形了。
setSinCos
簡介
設置sinCos
值,這個是控制Matrix
旋轉的,由于Matrix
已經封裝好了Rotate方法,所以這個并不常用。
// 方法一
void setSinCos (float sinValue, // 旋轉角度的sin值
float cosValue) // 旋轉角度的cos值
// 方法二
void setSinCos (float sinValue, // 旋轉角度的sin值
float cosValue, // 旋轉角度的cos值
float px, // 中心位置x坐標
float py) // 中心位置y坐標
示例
Matrix matrix = new Matrix();
// 旋轉90度
// sin90=1
// cos90=0
matrix.setSinCos(1f, 0f);
Log.i(TAG, "setSinCos:"+matrix.toShortString());
// 重置
matrix.reset();
// 旋轉90度
matrix.setRotate(90);
Log.i(TAG, "setRotate:"+matrix.toShortString());
setSinCos:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
setRotate:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
矩陣相關
方法 | 摘要 |
---|---|
invert | 求矩陣的逆矩陣 |
isAffine | 判斷當前矩陣是否為仿射矩陣,API21(5.0)才添加的方法。 |
isIdentity | 判斷當前矩陣是否為單位矩陣。 |
invert
求矩陣的逆矩陣,簡而言之就是計算與之前相反的矩陣,如果之前是平移200px
,則求的矩陣為反向平移200px
,如果之前是縮小到0.5f
,則結果是放大到2
倍。
boolean invert(Matrix inverse)
isAffine
判斷是否是仿射矩陣最重要的一點就是,直線是否仍為直線,簡單想一下就知道,不論平移,旋轉,錯切,縮放,直線變換后最終仍為直線,要想讓isAffine()
的結果變為false
,除非你能把直線掰彎。
boolean isAffine()
isIdentity
判斷是否為單位矩陣。
實用技巧
獲取View在屏幕上的絕對位置。
@Override
protected void onDraw(Canvas canvas) {
// 方式一:
float[] values = new float[9];
int[] location1 = new int[2];
Matrix matrix = canvas.getMatrix();
matrix.getValues(values);
location1[0] = (int) values[2];
location1[1] = (int) values[5];
Log.i(TAG, "location1 = " + Arrays.toString(location1));
// 方式二:
int[] location2 = new int[2];
this.getLocationOnScreen(location2);
Log.i(TAG, "location2 = " + Arrays.toString(location2));
}
location1 = [0, 243]
location2 = [0, 243]
利用setPolyToPoly制造3D效果
Android FoldingLayout 折疊布局 原理及實現(一)
Android FoldingLayout 折疊布局 原理及實現(二)