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];这其实还是没有脱离矩阵乘法,只是不知道后三位是如何应用的。了解这个对后边的连接矩阵的理解有好处,连接矩阵其实就是两个矩阵相乘后得到的新矩阵。
创建一个标准矩阵,应用后点的坐标不会有任何改变
创建一个src的深度复制,改变规则与src一致
如果obj为Matrix并且它的值与当前Matrix对象相等的会将会返回true
获取matrix的那9个值
将当前矩阵反转,并且反转后的值存入inverse中,如果当前矩阵不能反转,那么inverse不变,返回false,反转规则应该是满足 当前矩阵*inverse=标准矩阵,标准矩阵为[1,0,0,0,1,0,0,0,1];不过其实也不用想得那么复杂,比如当前matrix是setTranslate(10,20),那么反转后的matrix就是setTranslate(-10,-20);
判断当前矩阵是否为标准矩阵,这个函数比if (getType() == 0)运行的可能更快一些
用当前矩阵改变src中的点的坐标,然后将改变后的值对应的存入dst数组中,其中pointCount表示点的数目,(x,y)=(src[2*k],src[2*k+1])表示一个点的坐标,k取整数值,安卓中用数组存储点的坐标值的时候都是按如此法则存储的。
用当前矩阵改变pts中的值,然后存储在pts中,同上,pts也是存储点的坐标的数组
用当前矩阵改变src的值,并且存储到数组dst中
将一个半径为radius的圆的所有点坐标用matrix进行变换后,计算出该圆的半径并且返回该值。注意:要得到正确的值该圆默认是有中心的,个人注:说实话不明白这个函数有什么用
用matrix改变src的4个顶点的坐标,并将改变后的坐标调整后存储到dst中,(RectF只能存储改变后的左上角和右下角坐标,所以需要调整),返回的值跟rectStaysRect()一样,从字面意思可以认为src改变后仍然是RectF,那么就返回true
用matrix改变rect的4个顶点的坐标,并将改变后的坐标调整后存储到rect当中
用matrix改变dst中的向量值并且存储到src当中,注意:setTranslate(x,y)这样的matrix调用了这个函数后不会有任何反应,这样的matrix应该调用mapPoints
用matrix改变vecs中的值并且存储到vecs当中,同上,注意:setTranslate(x,y)这样的matrix调用了这个函数后不会有任何反应,这样的matrix应该调用mapPoints
同上,只不过vectorCount表示向量的数目,dstIndex,srcIndex分别表示各自的起始位置
将当前的matrix连接到other之后,并且将连接后的值写入当前matrix。 M‘=other*M,连接后变换的效果,相当于先变换M,然后在other变换
相当于这样:Matrix other=newMatrix();other.setRotate(degrees);postConcat(other);
先创建设置一个以0,0为原点旋转degrees度的矩阵other,然后将当前的matrix连接到other之后,并且将连接后的值写入当前matrix。
同上,不过改成这样Matrix other=newMatrix();other.setRotate(degrees,px,py);postConcat(other);
同上,无非是改成other.setScale(sx,sy);
同上
都是一样的,不过是创建的other有所不一样而已
同上边对应的函数功能类似,无非是other被连接在当前matrix之后,然后将连接后的值写入当前matrix当中
如果该matrix可以将rectF变换成rectF,那么该函数返回true,在标准变换,伸缩变换,平移变换,和多个90度的旋转变换时,该函数是返回true的
将当前matrix设置为标准矩阵
将src的内容深度复制给当前矩阵,如果src为null,那么当前矩阵变为标准矩阵
将当前matrix的值变为a和b的乘积
将当前matrix的值设置为这样的值,对src变换后可以得到dst的数据,pointCount表示点的数目,只能是0-4。设置成功返回true
将当前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)这两个矩阵得到了验证。
设置当前matrix,使作用于点坐标时使点坐标以点(0,0)为原点旋转degrees度。
设置当前matrix,使作用于点坐标时使点坐标以点(px,py)为原点旋转degrees度。在转换过程中,该原点不可改变
设置当前matrix,使作用于点坐标时使点坐标以(px,py)为支点伸缩sx,sy倍。(px,py)在转换过程中不能改变。这个解释有点蒙,验证了下发现其实就是x‘=(x+px)*sx,y‘=(y+py)*sy
这其实就是setScale(sx,sy,0,0);
这其实就是setSinCos(sinValue,cosValue,0,0);
设置当前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;
设置当前matrix,以px,py为支点进行倾斜kx,ky.公式变换应该为x‘=x+kx*(y-py),y‘=ky*(x-px)+y;
相当于setSkew(kx,ky,0,0);
设置matrix,应用时使点坐标(x,y)各自平移为(x+dx,y+dy);
复制9个数据给matrix,由于matrix的变形,或许这些数据会变成16位的数据,所以用getValues()可能不能得到与初始化相同的数据。不出意外的话,values的后三位要是0,0,1,否则可能该matrix变化后得不到你想要的点坐标
返回一个字符串用来描述该目标和数据,该类的子类是鼓励重写该函数的,详细描述该对象的类型和数据。默认的描述方式如下
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);
}
}
原文:http://www.cnblogs.com/xiaorenwu702/p/4190178.html