Matrix原理
来源:互联网 发布:黑马程序员32期 编辑:程序博客网 时间:2024/06/12 22:16
Matrix原理
转载出处:http://www.idtkm.com/customview/cutomview14/
Android自定义View系列
一、Matrix结构
在Android开发中,矩阵是一个非常强大且有趣的工具,在之前的一篇文章中对ColorMatrix的原理进行了详细的分析,用其实现了一些简单的颜色过滤功能,这一次我们来探寻一下同样强大的Matrix,它具有更改图像图形的有趣功能。我们先来看看Matrix的结构。
我们可以看到Matrix是一个3X3的矩阵。
- MSCALE_X、MSCALE_Y、MPERSP_2 分别表示X、Y、w(透视)的缩放
- MSKEW_X、MSKEW_Y 分别表示X、Y的错切
- MTRANS_X、MTRANS_Y 分别表示X、Y的平移
- MPERSP_0、MPERSP_1 分别表示X、Y方向上的透视
使用示例
在Android的很多地方其实都使用到了Matrix的方法,比如图片、Canvas、动画等,我们这里以图片为例,像在Canvas与ValueAnimator章节中一样,在onDraw
函数中我们先绘制一个坐标系,然后来绘制一个矩形。
// 平移画布canvas.translate(mWidth/2,mHeight/2);mPaint.setStrokeWidth(1);// 恢复画笔默认宽度// 绘制X轴canvas.drawLine(-mWidth/2*0.8f,0,mWidth/2*0.8f,0,mPaint);// 绘制Y轴canvas.drawLine(0,-mHeight/2*0.8f,0,mHeight/2*0.8f,mPaint);mPaint.setStrokeWidth(3);// 绘制X轴箭头canvas.drawLines(new float[]{ mWidth/2*0.8f,0,mWidth/2*0.8f*0.95f,-mWidth/2*0.8f*0.05f, mWidth/2*0.8f,0,mWidth/2*0.8f*0.95f,mWidth/2*0.8f*0.05f},mPaint);// 绘制Y轴箭头canvas.drawLines(new float[]{ 0,mHeight/2*0.8f,mWidth/2*0.8f*0.05f,mHeight/2*0.8f-mWidth/2*0.8f*0.05f, 0,mHeight/2*0.8f,-mWidth/2*0.8f*0.05f,mHeight/2*0.8f-mWidth/2*0.8f*0.05f,},mPaint);// 创建矩阵mMatrix = new Matrix();/** * 测试的Matrix操作 */// 绘制图片canvas.drawBitmap(mBitmap,mMatrix,null);
二、Matrix原理
1、缩放变换
将点的X轴和y轴方向分别缩放和倍。x、y的计算结果为 :
用矩阵表示 :
效果如图所示 :
使用示例
现在我们使用Matrix
自带的setScale
方法 :
/** * 测试的Matrix操作 */mMatrix.setScale(0.5f,0.5f);Log.d("TAG",mMatrix.toString());// LogD/TAG: Matrix{[0.5, 0.0, 0.0][0.0, 0.5, 0.0][0.0, 0.0, 1.0]}
2、错切变换
错切变换的效果就是让所有点的x坐标(或者y坐标)保持不变,而对于的y坐标(或者x坐标)则按照比例发生平移。
水平错切
保持y不变,但其x坐标则按比例发生平移。x、y的计算结果为 :
用矩阵表示 :
效果如图所示 :
垂直错切
保持x不变,但其y坐标则按比例发生平移。x、y的计算结果为 :
用矩阵表示 :
效果如图所示 :
当然你也可以同时进行水平错切和垂直错切的变换。
使用示例
现在我们使用Matrix
自带的setSkew
方法 :
/** * 测试的Matrix操作 */mMatrix.setSkew(0f,0.5f);Log.d("TAG",mMatrix.toString());// LogD/TAG: Matrix{[1.0, 0.0, 0.0][0.5, 1.0, 0.0][0.0, 0.0, 1.0]}
3、平移变换
假设有坐标为,将其点进行平移,移动到点,其x、y计算结果为 :
用矩阵表示 :
效果如图所示 :
使用示例
现在我们使用Matrix
自带的setTranslate
方法 :
/** * 测试的Matrix操作 */mMatrix.setTranslate(-200,-200);Log.d("TAG",mMatrix.toString());// LogD/TAG: Matrix{[1.0, 0.0, -200.0][0.0, 1.0, -200.0][0.0, 0.0, 1.0]}
4、旋转变换
假设有一点坐标为,距离原点为r,与x轴方向的夹角为α,绕原点旋转θ后,变换为点,其变换前后各点计算结果为 :
用矩阵表示为 :
效果如图所示 :
使用示例
现在我们使用Matrix
自带的setRotate
方法 :
/** * 测试的Matrix操作 */mMatrix.setRotate(180);Log.d("TAG",mMatrix.toString());// LogD/TAG: Matrix{[-1.0, -0.0, 0.0][0.0, -1.0, 0.0][0.0, 0.0, 1.0]}
5、透视变换
我们在之前的变换中,一直没有说到最后一行的三个参数MPERSP_0、MPERSP_1、MPERSP_2
,这里我们来稍微聊聊这三个参数所表示的透视。我们一般在图像中的一个点将使用如下方式进行表示(x, y, w),而Android中的二维矩阵计算是基于齐次坐标的,齐次坐标要求w的值为1,所以这个点的表示方法就变化为(x/w, y/w, 1)。
透视变换的效果其实类似于投影机的方式,我们看下w=3时,坐标(15,21,3)的效果 :
现在看下(15,21,3)计算出的齐次坐标系坐标(5,7,1)的效果 :
根据这个规则,也就解释了我们在使用过程中修改MPERSP_2
参数时,图像会发生的类似缩放的效果,其实就是透视变换的效果。
使用示例
现在我们使用Matrix
自带的setValues
方法 :
/** * 测试的Matrix操作 */mMatrix.setValues(new float[]{1, 0, 0, 0, 1, 0, 0, 0, 1.5f});Log.d("TAG",mMatrix.toString());// LogD/TAG: Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.5]}
三、Matrix前乘与后乘
Matrix前乘与后乘的情况跟我在之前的文章ColorMatrix详解中ColorMatrix相乘章节所描述的基本相同。
前乘
前乘相当于,当前矩阵乘以输入的矩阵
示例如下:
mMatrix.reset();mMatrix.preScale(sx,sy);mMatrix.preTranslate(dx,dy);
用矩阵表示为 :
后乘
后乘相当于,输入的矩阵乘以当前矩阵
mMatrix.reset();mMatrix.postScale(sx,sy);mMatrix.postTranslate(dx,dy);
四、总结
本文深入分析了Matrix的原理,并讲解了其常用方法和前后乘的方法。如果在阅读过程中,有任何疑问与问题,欢迎与我联系。
GitHub:https://github.com/Idtk
博客:http://www.idtkm.com
微博:http://weibo.com/Idtk
邮箱:Idtkma@gmail.com
参考
Matrix
Android Matrix
Android中关于矩阵(Matrix)前乘后乘的一些认识
齐次坐标系入门级思考
次坐标和投影
变换矩阵
- Matrix原理
- Matrix变换原理
- android Matrix原理
- Matrix的原理
- Android Matrix原理
- Android Matrix的数学原理
- Matrix学习笔记(一):原理
- 从原理详解Android Matrix
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android矩阵原理详解(Matrix,ColorMatrix)
- Android的Matrix图像变化原理
- Android中图像变换Matrix的原理
- Android中图像变换Matrix的原理
- Android Matrix 的使用以及原理
- 安卓自定义View进阶-Matrix原理
- 关于C++中如何判断文件,目录存在的若干方法
- 数据库分库分表(sharding)系列(四) 多数据源的事务处理
- 高效软文营销写作技巧:产生共鸣方是王道
- 用两个栈模拟队列
- 一起写RPC框架(二十五)RPC测试篇二---服务消费者和服务提供者直连测试
- Matrix原理
- [矩阵乘法]数列
- Missing contentDescription attribute on image
- AndroidStudio Gradle APP打包小技巧
- Android中的普通对话框、单选对话框、多选对话框、带Icon的对话框、以及自定义Adapter和自定义View对话框详解
- 20161012MYSQL密码复杂度设置
- android学习--UI控件
- C++ STL中的vector的内存分配与释放
- 实际用户ID,有效用户ID及设置用户ID详解