溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

android中如何使用graphics.Matrix類

發(fā)布時(shí)間:2021-06-26 17:03:08 來源:億速云 閱讀:215 作者:Leah 欄目:移動(dòng)開發(fā)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)android中如何使用graphics.Matrix類,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Matrix類包含了一個(gè)3x3的矩陣用來改變坐標(biāo),它沒有一個(gè)構(gòu)造器來初始化它里邊的內(nèi)容,所以創(chuàng)建實(shí)例后需要調(diào)用reset()方法生成一個(gè)標(biāo)準(zhǔn)matrix,或者調(diào)用set..一類的函數(shù),比如setTranslate, setRotate,,該函數(shù)將會(huì)決定matrix如何來改變坐標(biāo)。SDK里邊沒有講述Matrix的3x3矩陣是如何改變點(diǎn)的坐標(biāo)值的,但是我在代碼里邊通過打印那9個(gè)點(diǎn)的值時(shí),大致可以得到如下結(jié)論,9個(gè)值[a,b,c,d,e,f,g,h,i],坐標(biāo)[x,y],當(dāng)g=0,h=0,i=1,的時(shí)候,坐標(biāo)是這樣變換的,x'=a*x+b*y+c;y'=d*x+e*y+f;當(dāng)調(diào)用setTranslate(10,20)之后,matrix的值就變成[1,0,10,0,1,20,0,0,1];這其實(shí)還是沒有脫離矩陣乘法,只是不知道后三位是如何應(yīng)用的。了解這個(gè)對后邊的連接矩陣的理解有好處,連接矩陣其實(shí)就是兩個(gè)矩陣相乘后得到的新矩陣。

public Matrix()
創(chuàng)建一個(gè)標(biāo)準(zhǔn)矩陣,應(yīng)用后點(diǎn)的坐標(biāo)不會(huì)有任何改變

public Matrix(Matrix src)
創(chuàng)建一個(gè)src的深度復(fù)制,改變規(guī)則與src一致

public boolean equals(Object obj)
如果obj為Matrix并且它的值與當(dāng)前Matrix對象相等的會(huì)將會(huì)返回true

public void getValues(float[] values)
獲取matrix的那9個(gè)值

public boolean invert(Matrix inverse)
將當(dāng)前矩陣反轉(zhuǎn),并且反轉(zhuǎn)后的值存入inverse中,如果當(dāng)前矩陣不能反轉(zhuǎn),那么inverse不變,返回false,反轉(zhuǎn)規(guī)則應(yīng)該是滿足 當(dāng)前矩陣*inverse=標(biāo)準(zhǔn)矩陣,標(biāo)準(zhǔn)矩陣為[1,0,0,0,1,0,0,0,1];不過其實(shí)也不用想得那么復(fù)雜,比如當(dāng)前matrix是setTranslate(10,20),那么反轉(zhuǎn)后的matrix就是setTranslate(-10,-20);

public boolean isIdentity()
判斷當(dāng)前矩陣是否為標(biāo)準(zhǔn)矩陣,這個(gè)函數(shù)比if (getType() == 0)運(yùn)行的可能更快一些

public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, int pointCount)
用當(dāng)前矩陣改變src中的點(diǎn)的坐標(biāo),然后將改變后的值對應(yīng)的存入dst數(shù)組中,其中pointCount表示點(diǎn)的數(shù)目,(x,y)=(src[2*k],src[2*k+1])表示一個(gè)點(diǎn)的坐標(biāo),k取整數(shù)值,安卓中用數(shù)組存儲(chǔ)點(diǎn)的坐標(biāo)值的時(shí)候都是按如此法則存儲(chǔ)的。

public void mapPoints(float[] pts)
用當(dāng)前矩陣改變pts中的值,然后存儲(chǔ)在pts中,同上,pts也是存儲(chǔ)點(diǎn)的坐標(biāo)的數(shù)組

public void mapPoints(float[] dst, float[] src)
用當(dāng)前矩陣改變src的值,并且存儲(chǔ)到數(shù)組dst中

public float mapRadius(float radius)
將一個(gè)半徑為radius的圓的所有點(diǎn)坐標(biāo)用matrix進(jìn)行變換后,計(jì)算出該圓的半徑并且返回該值。注意:要得到正確的值該圓默認(rèn)是有中心的,個(gè)人注:說實(shí)話不明白這個(gè)函數(shù)有什么用

public boolean mapRect(RectF dst,RectF src)
用matrix改變src的4個(gè)頂點(diǎn)的坐標(biāo),并將改變后的坐標(biāo)調(diào)整后存儲(chǔ)到dst中,(RectF只能存儲(chǔ)改變后的左上角和右下角坐標(biāo),所以需要調(diào)整),返回的值跟rectStaysRect()一樣,從字面意思可以認(rèn)為src改變后仍然是RectF,那么就返回true

public boolean mapRect(RectF rect)
用matrix改變r(jià)ect的4個(gè)頂點(diǎn)的坐標(biāo),并將改變后的坐標(biāo)調(diào)整后存儲(chǔ)到rect當(dāng)中

public void mapVectors(float[] dst, float[] src)
用matrix改變dst中的向量值并且存儲(chǔ)到src當(dāng)中,注意:setTranslate(x,y)這樣的matrix調(diào)用了這個(gè)函數(shù)后不會(huì)有任何反應(yīng),這樣的matrix應(yīng)該調(diào)用mapPoints

public void mapVectors(float[] vecs)
用matrix改變vecs中的值并且存儲(chǔ)到vecs當(dāng)中,同上,注意:setTranslate(x,y)這樣的matrix調(diào)用了這個(gè)函數(shù)后不會(huì)有任何反應(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)
將當(dāng)前的matrix連接到other之后,并且將連接后的值寫入當(dāng)前matrix。 M‘=other*M,連接后變換的效果,相當(dāng)于先變換M,然后在other變換

public boolean postRotate(float degrees)
相當(dāng)于這樣:

Matrix other=newMatrix();
other.setRotate(degrees);
postConcat(other);

先創(chuàng)建設(shè)置一個(gè)以0,0為原點(diǎn)旋轉(zhuǎn)degrees度的矩陣other,然后將當(dāng)前的matrix連接到other之后,并且將連接后的值寫入當(dāng)前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被連接在當(dāng)前matrix之后,然后將連接后的值寫入當(dāng)前matrix當(dāng)中

public boolean rectStaysRect()
如果該matrix可以將rectF變換成rectF,那么該函數(shù)返回true,在標(biāo)準(zhǔn)變換,伸縮變換,平移變換,和多個(gè)90度的旋轉(zhuǎn)變換時(shí),該函數(shù)是返回true的

public void reset()
將當(dāng)前matrix設(shè)置為標(biāo)準(zhǔn)矩陣

public void set(Matrix src)
將src的內(nèi)容深度復(fù)制給當(dāng)前矩陣,如果src為null,那么當(dāng)前矩陣變?yōu)闃?biāo)準(zhǔn)矩陣

public boolean setConcat(Matrix a,Matrix b)
將當(dāng)前matrix的值變?yōu)閍和b的乘積

public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)
將當(dāng)前matrix的值設(shè)置為這樣的值,對src變換后可以得到dst的數(shù)據(jù),pointCount表示點(diǎn)的數(shù)目,只能是0-4。設(shè)置成功返回true

public boolean setRectToRect(RectF src,RectF dst, Matrix.ScaleToFit stf)
將當(dāng)前matrix的值設(shè)置為這樣的值,對src進(jìn)行變換后可以得到dst,因兩者都是RectF,所以該matrix的值只能是伸縮和平移的組合,設(shè)置成功了返回true,stf為伸縮參數(shù),這個(gè)Matrix.ScaleToFit伸縮參數(shù)有什么名堂呢,它有四個(gè)常量,每個(gè)常量應(yīng)用后會(huì)導(dǎo)致matrix有什么結(jié)果呢,根據(jù)那4個(gè)常量的文字說明可知,CENTER,END,START表示得到的伸縮矩陣m,m對src進(jìn)行變換后得到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)這兩個(gè)矩陣得到了驗(yàn)證。

public void setRotate(float degrees)
設(shè)置當(dāng)前matrix,使作用于點(diǎn)坐標(biāo)時(shí)使點(diǎn)坐標(biāo)以點(diǎn)(0,0)為原點(diǎn)旋轉(zhuǎn)degrees度。

public void setRotate(float degrees, float px, float py)
設(shè)置當(dāng)前matrix,使作用于點(diǎn)坐標(biāo)時(shí)使點(diǎn)坐標(biāo)以點(diǎn)(px,py)為原點(diǎn)旋轉(zhuǎn)degrees度。在轉(zhuǎn)換過程中,該原點(diǎn)不可改變

public void setScale(float sx, float sy, float px, float py)
設(shè)置當(dāng)前matrix,使作用于點(diǎn)坐標(biāo)時(shí)使點(diǎn)坐標(biāo)以(px,py)為支點(diǎn)伸縮sx,sy倍。(px,py)在轉(zhuǎn)換過程中不能改變。這個(gè)解釋有點(diǎn)蒙,驗(yàn)證了下發(fā)現(xiàn)其實(shí)就是x'=(x+px)*sx,y'=(y+py)*sy

public void setScale(float sx, float sy)
這其實(shí)就是setScale(sx,sy,0,0);

public void setSinCos(float sinValue, float cosValue)
這其實(shí)就是setSinCos(sinValue,cosValue,0,0);

public void setSinCos(float sinValue, float cosValue, float px, float py)
設(shè)置當(dāng)前matrix,以px,py為支點(diǎn)進(jìn)行旋轉(zhuǎn)變換,變換方式與sinValue,cosValue的值有關(guān),經(jīng)過驗(yàn)證,可以得到近似換算公式為:

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è)置當(dāng)前matrix,以px,py為支點(diǎn)進(jìn)行傾斜kx,ky.公式變換應(yīng)該為

x'=x+kx*(y-py),y'=ky*(x-px)+y;

public void setSkew(float kx, float ky)
相當(dāng)于setSkew(kx,ky,0,0);

public void setTranslate(float dx, float dy)
設(shè)置matrix,應(yīng)用時(shí)使點(diǎn)坐標(biāo)(x,y)各自平移為(x+dx,y+dy);

public void setValues(float[] values)
復(fù)制9個(gè)數(shù)據(jù)給matrix,由于matrix的變形,或許這些數(shù)據(jù)會(huì)變成16位的數(shù)據(jù),所以用getValues()可能不能得到與初始化相同的數(shù)據(jù)。不出意外的話,values的后三位要是0,0,1,否則可能該matrix變化后得不到你想要的點(diǎn)坐標(biāo)

public String toShortString ()
public String toString ()
返回一個(gè)字符串用來描述該目標(biāo)和數(shù)據(jù),該類的子類是鼓勵(lì)重寫該函數(shù)的,詳細(xì)描述該對象的類型和數(shù)據(jù)。默認(rèn)的描述方式如下

getClass().getName() + '@' + Integer.toHexString(hashCode())

補(bǔ)充源碼如下

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類了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI