常用的图形变换包括:平移(矩阵T),旋转(矩阵R),缩放(矩阵S)。
图形是实质由点形成的。
图形变换是矩阵相乘的结果,分为前乘和后乘,对应矩阵的左乘和右乘。在矩阵中,排列在右的矩阵有更高的权,因此右乘优先于左乘。
数学知识补充:2*2矩阵相乘示意图
数学知识补充:矩阵在变换坐标过程中相乘
起始坐标系:
拉伸x轴坐标系:
这个变换过程中的矩阵:
而在计算机中图形变换我们用的是3*3矩阵示意图,比起2*2矩阵添加了第三维坐标,其值都为1。
android中的图形变换时如果没有指定中心点,默认是原点。
举个例子:
Matrix matrix = new Matrix();
matrix.reset(); //设置矩阵
matrix.postScale(0.5f,0.5f); //缩放0.5倍
matrix.preTranslate(-100,-100); //平移
matrix.postTranslate(100,100);
查看文档说明:
postTranslate: M’ = T(dx, dy) * M
preTranslate : M’ = M * T(dx, dy)
postScale : M’ = S(sx, sy) * M
可以发现postTranslate和postScale是左乘操作,preTranslate是右乘操作。
因此,上面的这段代码的执行步骤是:
1)在当前的矩阵左边加一个Scale的操作,因为之前没有其的操作(reset了),那么当前的矩阵其实就只是 S 了。
2)在当前的矩阵(S)执行前,先执行一个平移到原点的操作(preTranslate),其实也就是进行右乘(S * T)。
3)在当前的矩阵(S * T)执行后,再执行一个从原点平移到中心点的操作(postTranslate),也就是进行一个左乘(-T * S * T)。
以代码注解:
int id = view.getId();
switch(id){
case R.id.half:
//缩放,返回布尔值,两个参数为别为X,Y方向上的缩放比例
matrix.postScale(0.5f,0.5f);
//绘制时添加一个视图drawable对象转型矩阵,图片保存在了drawable文件下
imageView.setImageMatrix(matrix);
break;
case R.id.translate:
//平移
matrix.postTranslate(-100,-100);
imageView.setImageMatrix(matrix);
break;
case R.id.rotate:
//旋转,后两个参数是中心点
matrix.postRotate(30,imageView.getWidth()/2,imageView.getHeight()/2);
imageView.setImageMatrix(matrix);
break;
case R.id.skew:
//倾斜,后两个参数分别为X,Y方向上的倾斜距离
matrix.postSkew(1.2f,1.3f);
imageView.setImageMatrix(matrix);
break;
case R.id.reset:
//每一次set都会重新排列矩阵
matrix.reset();
imageView.setImageMatrix(matrix);
imageView.scrollTo(0,0);
break;
}