您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關android中如何使用graphics.Matrix類,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
Matrix類包含了一個3x3的矩陣用來改變坐標,它沒有一個構造器來初始化它里邊的內容,所以創建實例后需要調用reset()
方法生成一個標準matrix,或者調用set..一類的函數,比如setTranslate, setRotate,,該函數將會決定matrix如何來改變坐標。SDK里邊沒有講述Matrix的3x3矩陣是如何改變點的坐標值的,但是我在代碼里邊通過打印那9個點的值時,大致可以得到如下結論,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;當調用setTranslate(10,20)之后,matrix的值就變成[1,0,10,0,1,20,0,0,1];這其實還是沒有脫離矩陣乘法,只是不知道后三位是如何應用的。了解這個對后邊的連接矩陣的理解有好處,連接矩陣其實就是兩個矩陣相乘后得到的新矩陣。
public Matrix()
創建一個標準矩陣,應用后點的坐標不會有任何改變
public Matrix(Matrix src)
創建一個src的深度復制,改變規則與src一致
public boolean equals(Object obj)
如果obj為Matrix并且它的值與當前Matrix對象相等的會將會返回true
public void getValues(float[] values)
獲取matrix的那9個值
public boolean invert(Matrix inverse)
將當前矩陣反轉,并且反轉后的值存入inverse中,如果當前矩陣不能反轉,那么inverse不變,返回false,反轉規則應該是滿足 當前矩陣*inverse=標準矩陣,標準矩陣為[1,0,0,0,1,0,0,0,1];不過其實也不用想得那么復雜,比如當前matrix是setTranslate(10,20),那么反轉后的matrix就是setTranslate(-10,-20);
public boolean isIdentity()
判斷當前矩陣是否為標準矩陣,這個函數比if (getType() == 0)運行的可能更快一些
public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, int pointCount)
用當前矩陣改變src中的點的坐標,然后將改變后的值對應的存入dst數組中,其中pointCount表示點的數目,(x,y)=(src[2*k],src[2*k+1])表示一個點的坐標,k取整數值,安卓中用數組存儲點的坐標值的時候都是按如此法則存儲的。
public void mapPoints(float[] pts)
用當前矩陣改變pts中的值,然后存儲在pts中,同上,pts也是存儲點的坐標的數組
public void mapPoints(float[] dst, float[] src)
用當前矩陣改變src的值,并且存儲到數組dst中
public float mapRadius(float radius)
將一個半徑為radius的圓的所有點坐標用matrix進行變換后,計算出該圓的半徑并且返回該值。注意:要得到正確的值該圓默認是有中心的,個人注:說實話不明白這個函數有什么用
public boolean mapRect(RectF dst,RectF src)
用matrix改變src的4個頂點的坐標,并將改變后的坐標調整后存儲到dst中,(RectF只能存儲改變后的左上角和右下角坐標,所以需要調整),返回的值跟rectStaysRect()一樣,從字面意思可以認為src改變后仍然是RectF,那么就返回true
public boolean mapRect(RectF rect)
用matrix改變rect的4個頂點的坐標,并將改變后的坐標調整后存儲到rect當中
public void mapVectors(float[] dst, float[] src)
用matrix改變dst中的向量值并且存儲到src當中,注意:setTranslate(x,y)這樣的matrix調用了這個函數后不會有任何反應,這樣的matrix應該調用mapPoints
public void mapVectors(float[] vecs)
用matrix改變vecs中的值并且存儲到vecs當中,同上,注意:setTranslate(x,y)這樣的matrix調用了這個函數后不會有任何反應,這樣的matrix應該調用mapPoints
public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)
同上,只不過vectorCount表示向量的數目,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);
先創建設置一個以0,0為原點旋轉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)
都是一樣的,不過是創建的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)
同上邊對應的函數功能類似,無非是other被連接在當前matrix之后,然后將連接后的值寫入當前matrix當中
public boolean rectStaysRect()
如果該matrix可以將rectF變換成rectF,那么該函數返回true,在標準變換,伸縮變換,平移變換,和多個90度的旋轉變換時,該函數是返回true的
public void reset()
將當前matrix設置為標準矩陣
public void set(Matrix src)
將src的內容深度復制給當前矩陣,如果src為null,那么當前矩陣變為標準矩陣
public boolean setConcat(Matrix a,Matrix b)
將當前matrix的值變為a和b的乘積
public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)
將當前matrix的值設置為這樣的值,對src變換后可以得到dst的數據,pointCount表示點的數目,只能是0-4。設置成功返回true
public boolean setRectToRect(RectF src,RectF dst, Matrix.ScaleToFit stf)
將當前matrix的值設置為這樣的值,對src進行變換后可以得到dst,因兩者都是RectF,所以該matrix的值只能是伸縮和平移的組合,設置成功了返回true,stf為伸縮參數,這個Matrix.ScaleToFit伸縮參數有什么名堂呢,它有四個常量,每個常量應用后會導致matrix有什么結果呢,根據那4個常量的文字說明可知,CENTER,END,START表示得到的伸縮矩陣m,m對src進行變換后得到dst1,dst1跟src有同樣的寬高比例,dst1在dst的內部,不同的地方是CENTER的狀態是這樣的:dst1.left-dst.left=dst.right-dst1.right,dst1.top-dst.top=dst.bottom-dst1.bottom
END的狀態是這樣的:dst1.right=dst.right,dst1.bottom=dst.bottom
.START的狀態是這樣的:dst1.left=dst.left,dst1.top=dst.top;
至于FILL表示得到的伸縮矩陣m,通過它對src變換后得到的Rect就是dst,完全重合。結論通過RectF(0,0,10,10), RectF(0,0,20,30)這兩個矩陣得到了驗證。
public void setRotate(float degrees)
設置當前matrix,使作用于點坐標時使點坐標以點(0,0)為原點旋轉degrees度。
public void setRotate(float degrees, float px, float py)
設置當前matrix,使作用于點坐標時使點坐標以點(px,py)為原點旋轉degrees度。在轉換過程中,該原點不可改變
public void setScale(float sx, float sy, float px, float py)
設置當前matrix,使作用于點坐標時使點坐標以(px,py)為支點伸縮sx,sy倍。(px,py)在轉換過程中不能改變。這個解釋有點蒙,驗證了下發現其實就是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)
設置當前matrix,以px,py為支點進行旋轉變換,變換方式與sinValue,cosValue的值有關,經過驗證,可以得到近似換算公式為:
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)
設置當前matrix,以px,py為支點進行傾斜kx,ky.公式變換應該為
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)
設置matrix,應用時使點坐標(x,y)各自平移為(x+dx,y+dy);
public void setValues(float[] values)
復制9個數據給matrix,由于matrix的變形,或許這些數據會變成16位的數據,所以用getValues()可能不能得到與初始化相同的數據。不出意外的話,values的后三位要是0,0,1,否則可能該matrix變化后得不到你想要的點坐標
public String toShortString ()
public String toString ()
返回一個字符串用來描述該目標和數據,該類的子類是鼓勵重寫該函數的,詳細描述該對象的類型和數據。默認的描述方式如下
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); } }
上述就是小編為大家分享的android中如何使用graphics.Matrix類了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。