android.graphics.Matrix類用法分析
本文實例講述了android.graphics.Matrix類用法。分享給大家供大家參考,具體如下:
Matrix類包含了一個3x3的矩陣用來改變坐標,它沒有一個構(gòu)造器來初始化它里邊的內(nèi)容,所以創(chuàng)建實例后需要調(diào)用reset()方法生成一個標準matrix,或者調(diào)用set..一類的函數(shù),比如setTranslate, setRotate,,該函數(shù)將會決定matrix如何來改變坐標。SDK里邊沒有講述Matrix的3x3矩陣是如何改變點的坐標值的,但是我在代碼里邊通過打印那9個點的值時,大致可以得到如下結(jié)論,9個值[a,b,c,d,e,f,g,h,i],坐標[x,y],當g=0,h=0,i=1,的時候,坐標是這樣變換的,x'=a*x+b*y+c;y'=d*x+e*y+f;當調(diào)用setTranslate(10,20)之后,matrix的值就變成[1,0,10,0,1,20,0,0,1];這其實還是沒有脫離矩陣乘法,只是不知道后三位是如何應(yīng)用的。了解這個對后邊的連接矩陣的理解有好處,連接矩陣其實就是兩個矩陣相乘后得到的新矩陣。
public Matrix()
創(chuàng)建一個標準矩陣,應(yīng)用后點的坐標不會有任何改變
public Matrix(Matrix src)
創(chuàng)建一個src的深度復(fù)制,改變規(guī)則與src一致
public boolean equals(Object obj)
如果obj為Matrix并且它的值與當前Matrix對象相等的會將會返回true
public void getValues(float[] values)
獲取matrix的那9個值
public boolean invert(Matrix inverse)
將當前矩陣反轉(zhuǎn),并且反轉(zhuǎn)后的值存入inverse中,如果當前矩陣不能反轉(zhuǎn),那么inverse不變,返回false,反轉(zhuǎn)規(guī)則應(yīng)該是滿足 當前矩陣*inverse=標準矩陣,標準矩陣為[1,0,0,0,1,0,0,0,1];不過其實也不用想得那么復(fù)雜,比如當前matrix是setTranslate(10,20),那么反轉(zhuǎn)后的matrix就是setTranslate(-10,-20);
public boolean isIdentity()
判斷當前矩陣是否為標準矩陣,這個函數(shù)比if (getType() == 0)運行的可能更快一些
public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, int pointCount)
用當前矩陣改變src中的點的坐標,然后將改變后的值對應(yīng)的存入dst數(shù)組中,其中pointCount表示點的數(shù)目,(x,y)=(src[2*k],src[2*k+1])表示一個點的坐標,k取整數(shù)值,安卓中用數(shù)組存儲點的坐標值的時候都是按如此法則存儲的。
public void mapPoints(float[] pts)
用當前矩陣改變pts中的值,然后存儲在pts中,同上,pts也是存儲點的坐標的數(shù)組
public void mapPoints(float[] dst, float[] src)
用當前矩陣改變src的值,并且存儲到數(shù)組dst中
public float mapRadius(float radius)
將一個半徑為radius的圓的所有點坐標用matrix進行變換后,計算出該圓的半徑并且返回該值。注意:要得到正確的值該圓默認是有中心的,個人注:說實話不明白這個函數(shù)有什么用
public boolean mapRect(RectF dst,RectF src)
用matrix改變src的4個頂點的坐標,并將改變后的坐標調(diào)整后存儲到dst中,(RectF只能存儲改變后的左上角和右下角坐標,所以需要調(diào)整),返回的值跟rectStaysRect()一樣,從字面意思可以認為src改變后仍然是RectF,那么就返回true
public boolean mapRect(RectF rect)
用matrix改變rect的4個頂點的坐標,并將改變后的坐標調(diào)整后存儲到rect當中
public void mapVectors(float[] dst, float[] src)
用matrix改變dst中的向量值并且存儲到src當中,注意:setTranslate(x,y)這樣的matrix調(diào)用了這個函數(shù)后不會有任何反應(yīng),這樣的matrix應(yīng)該調(diào)用mapPoints
public void mapVectors(float[] vecs)
用matrix改變vecs中的值并且存儲到vecs當中,同上,注意:setTranslate(x,y)這樣的matrix調(diào)用了這個函數(shù)后不會有任何反應(yīng),這樣的matrix應(yīng)該調(diào)用mapPoints
public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)
同上,只不過vectorCount表示向量的數(shù)目,dstIndex,srcIndex分別表示各自的起始位置
public boolean postConcat(Matrix other)
將當前的matrix連接到other之后,并且將連接后的值寫入當前matrix。 M‘=other*M,連接后變換的效果,相當于先變換M,然后在other變換
public boolean postRotate(float degrees)
相當于這樣:
Matrix other=newMatrix(); other.setRotate(degrees); postConcat(other);
先創(chuàng)建設(shè)置一個以0,0為原點旋轉(zhuǎn)degrees度的矩陣other,然后將當前的matrix連接到other之后,并且將連接后的值寫入當前matrix。
public boolean postRotate(float degrees, float px, float py)
同上,不過改成這樣
Matrix other=newMatrix(); other.setRotate(degrees,px,py); postConcat(other);
public boolean postScale(float sx, float sy)
同上,無非是改成
other.setScale(sx,sy);
public boolean postScale(float sx, float sy, float px, float py)
同上
public boolean postSkew(float kx, float ky)
public boolean postSkew(float kx, float ky, float px, float py)
public boolean postTranslate(float dx, float dy)
都是一樣的,不過是創(chuàng)建的other有所不一樣而已
public boolean preConcat(Matrix other)
public boolean preRotate(float degrees)
public boolean preRotate(float degrees, float px, float py)
public boolean preScale(float sx, float sy)
public boolean preScale(float sx, float sy, float px, float py)
public boolean preSkew(float kx, float ky)
public boolean preSkew(float kx, float ky, float px, float py)
public boolean preTranslate(float dx, float dy)
同上邊對應(yīng)的函數(shù)功能類似,無非是other被連接在當前matrix之后,然后將連接后的值寫入當前matrix當中
public boolean rectStaysRect()
如果該matrix可以將rectF變換成rectF,那么該函數(shù)返回true,在標準變換,伸縮變換,平移變換,和多個90度的旋轉(zhuǎn)變換時,該函數(shù)是返回true的
public void reset()
將當前matrix設(shè)置為標準矩陣
public void set(Matrix src)
將src的內(nèi)容深度復(fù)制給當前矩陣,如果src為null,那么當前矩陣變?yōu)闃藴示仃?/p>
public boolean setConcat(Matrix a,Matrix b)
將當前matrix的值變?yōu)閍和b的乘積
public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)
將當前matrix的值設(shè)置為這樣的值,對src變換后可以得到dst的數(shù)據(jù),pointCount表示點的數(shù)目,只能是0-4。設(shè)置成功返回true
public boolean setRectToRect(RectF src,RectF dst, Matrix.ScaleToFit stf)
將當前matrix的值設(shè)置為這樣的值,對src進行變換后可以得到dst,因兩者都是RectF,所以該matrix的值只能是伸縮和平移的組合,設(shè)置成功了返回true,stf為伸縮參數(shù),這個Matrix.ScaleToFit伸縮參數(shù)有什么名堂呢,它有四個常量,每個常量應(yīng)用后會導(dǎo)致matrix有什么結(jié)果呢,根據(jù)那4個常量的文字說明可知,CENTER,END,START表示得到的伸縮矩陣m,m對src進行變換后得到dst1,dst1跟src有同樣的寬高比例,dst1在dst的內(nèi)部,不同的地方是CENTER的狀態(tài)是這樣的:dst1.left-dst.left=dst.right-dst1.right,dst1.top-dst.top=dst.bottom-dst1.bottomEND的狀態(tài)是這樣的:dst1.right=dst.right,dst1.bottom=dst.bottom.START的狀態(tài)是這樣的:dst1.left=dst.left,dst1.top=dst.top;至于FILL表示得到的伸縮矩陣m,通過它對src變換后得到的Rect就是dst,完全重合。結(jié)論通過RectF(0,0,10,10), RectF(0,0,20,30)這兩個矩陣得到了驗證。
public void setRotate(float degrees)
設(shè)置當前matrix,使作用于點坐標時使點坐標以點(0,0)為原點旋轉(zhuǎn)degrees度。
public void setRotate(float degrees, float px, float py)
設(shè)置當前matrix,使作用于點坐標時使點坐標以點(px,py)為原點旋轉(zhuǎn)degrees度。在轉(zhuǎn)換過程中,該原點不可改變
public void setScale(float sx, float sy, float px, float py)
設(shè)置當前matrix,使作用于點坐標時使點坐標以(px,py)為支點伸縮sx,sy倍。(px,py)在轉(zhuǎn)換過程中不能改變。這個解釋有點蒙,驗證了下發(fā)現(xiàn)其實就是x'=(x+px)*sx,y'=(y+py)*sy
public void setScale(float sx, float sy)
這其實就是setScale(sx,sy,0,0);
public void setSinCos(float sinValue, float cosValue)
這其實就是setSinCos(sinValue,cosValue,0,0);
public void setSinCos(float sinValue, float cosValue, float px, float py)
設(shè)置當前matrix,以px,py為支點進行旋轉(zhuǎn)變換,變換方式與sinValue,cosValue的值有關(guān),經(jīng)過驗證,可以得到近似換算公式為:
x'=cosValue*x-sinValue*y+(1-cosValue)*px+sinValue*py; y'=sinValue*x+cosValue*y-sinValue*px+(1-cosValue)*py;
public void setSkew(float kx, float ky, float px, float py)
設(shè)置當前matrix,以px,py為支點進行傾斜kx,ky.公式變換應(yīng)該為
x'=x+kx*(y-py),y'=ky*(x-px)+y;
public void setSkew(float kx, float ky)
相當于setSkew(kx,ky,0,0);
public void setTranslate(float dx, float dy)
設(shè)置matrix,應(yīng)用時使點坐標(x,y)各自平移為(x+dx,y+dy);
public void setValues(float[] values)
復(fù)制9個數(shù)據(jù)給matrix,由于matrix的變形,或許這些數(shù)據(jù)會變成16位的數(shù)據(jù),所以用getValues()可能不能得到與初始化相同的數(shù)據(jù)。不出意外的話,values的后三位要是0,0,1,否則可能該matrix變化后得不到你想要的點坐標
public String toShortString ()
public String toString ()
返回一個字符串用來描述該目標和數(shù)據(jù),該類的子類是鼓勵重寫該函數(shù)的,詳細描述該對象的類型和數(shù)據(jù)。默認的描述方式如下
getClass().getName() + '@' + Integer.toHexString(hashCode())
補充源碼如下
package com.hahajlu;
import Android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
public class MatrixActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
}
class SampleView extends View
{
Matrix mt1=new Matrix();
Matrix mt2=new Matrix();
public SampleView(Context context)
{
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
float p[]=new float[]{100.f,100.f};
// mt1.setRotate(90);
mt1.setValues(new float[]{1,0,1,0,1,3,1,2,1});
// mt1.mapPoints(p);
// mt1.setScale(0.5f, 0.5f);
// mt1.mapPoints(p);
// mt1.setTranslate(10.f, 10.f);
//mt1.invert(mt2);
// mt1.setRectToRect(new RectF(0,0,10,10), new RectF(0,0,20,30), Matrix.ScaleToFit.FILL);
// mt1.setScale(0.5f, 0.5f, 20f, 30f);
// mt1.setSinCos(0.5f, 0.6f,30.f,20.f);
// mt1.setSkew(10f, 15f, 20f, 32f);
float values[]=new float[9];
mt1.getValues(values);
mt1.mapPoints(p);
Paint paint=new Paint();
paint.setColor(Color.BLACK);
canvas.drawColor(Color.WHITE);
canvas.drawText("為了", p[0], p[1], paint);
System.out.println("x="+p[0]+"y="+p[1]);
for(int i=0;i<9;i++)
System.out.println("values="+values[i]);
// float radiu=mt1.mapRadius(10.f);
// System.out.println("radiu="+radiu);
super.onDraw(canvas);
}
}
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計有所幫助。
相關(guān)文章
Android onSaveInstanceState和onRestoreInstanceState觸發(fā)的時機
這篇文章主要介紹了Android onSaveInstanceState和onRestoreInstanceState觸發(fā)的時機的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android在線更新SDK的方法(使用國內(nèi)鏡像)
這篇文章主要介紹了Android在線更新SDK的方法,分別介紹了修改hosts文件使用谷歌官方鏡像更新及使用國內(nèi)鏡像更新SDK的方法,非常簡單實用,需要的朋友可以參考下2015-12-12
Android ListView滾動到底后自動加載數(shù)據(jù)
這篇文章主要為大家詳細介紹了Android之ListView滾動到底后自動加載數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
Android中設(shè)置WebView禁止縮放網(wǎng)頁的步驟
在Android中如果你想要禁止WebView縮放網(wǎng)頁,可以通過設(shè)置WebView的一些屬性來實現(xiàn),這篇文章主要給大家介紹了關(guān)于Android中設(shè)置WebView禁止縮放網(wǎng)頁的步驟,需要的朋友可以參考下2024-05-05
詳解Android_性能優(yōu)化之ViewPager加載成百上千高清大圖oom解決方案
這篇文章主要介紹了詳解Android_性能優(yōu)化之ViewPager加載成百上千高清大圖oom解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-12-12
Android開發(fā)自定義控件之折線圖實現(xiàn)方法詳解
這篇文章主要介紹了Android開發(fā)自定義控件之折線圖實現(xiàn)方法,結(jié)合實例形式詳細分析了Android自定義控件中折線圖原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-05-05
Android開發(fā)入門之Notification用法分析
這篇文章主要介紹了Android中Notification用法,較為詳細的分析了Notification的功能、使用步驟與相關(guān)注意事項,需要的朋友可以參考下2016-07-07

