在上一篇文章中,我们讲到,在Android中,scale(缩放),rotation(旋转)和 translation(平移)都是以矩阵(Matrix)的形式定义的,实际上在图形学中,这些平面图形的变换都是以矩阵的形式存在的。先来回顾一下,下面,左中右分别scale(缩放),rotation(旋转)和 translation(平移)在Android中的矩阵表示:
如果只是单纯的应用某一个变换,我们都知道直接用矩阵去乘上对应的点就可以了。但是对于缩放和旋转来说,它们的轴点是基于原点(0,0)的,如下图,我们将它缩小1倍,代码如下:
public void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, null);
matrix.reset();
matrix.postScale(0.5f, 0.5f);
canvas.drawBitmap(bitmap, matrix, null);
}
则其效果如右图所示:
那么我们如果想让它基于图片中心缩放,应该该怎么办?我们上一篇文章也说过了,要用到组合变换,
1)先将图片由中心平移到原点,这是应用变换 T
2)对图应用缩放变换 S
3)再将图片平移回到中心,应用变换 -T
下面给出它们的组合变换的公式:
在Android中的代码如下:
public void onDraw(Canvas canvas){
canvas.drawBitmap(bitmap, 0, 0, null);
matrix.reset();
matrix.postScale(0.5f, 0.5f);
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
canvas.drawBitmap(bitmap, matrix, null);
}
我们看一下加上平移之后的效果图(其中pivotX 和 pivotY 是图片的中心):
我们看到代码中,我们在进行了scale之后呢,还给图片设置了下面两个平移的变换:
matrix.preTranslate(-pivotX, -pivotY);
matrix.postTranslate(pivotX, pivotY);
什么是PreTranlsate呢,什么又是postTranslate呢?我们先来看一下Android中的定义吧。
preTranslate:
/**
* Preconcats the matrix with the specified translation.
* M' = M * T(dx, dy)
*/
public boolean preTranslate(float dx, float dy) {
return native_preTranslate(native_instance, dx, dy);
}
postTranslate:
/**
* Postconcats the matrix with the specified translation.
* M' = T(dx, dy) * M
*/
public boolean postTranslate(float dx, float dy) {
return native_postTranslate(native_instance, dx, dy);
}
我们可以看到,pre是拿当前的矩阵乘以T,而post是拿T来乘以当前的矩阵,(矩阵的乘法是不满足交换率的,所以这两种乘法的结果是不一样的)
在图形学中,矩阵M右乘A,表示的是 A * M,而矩阵 M 左乘 A,则表示的是 M * A,可以形象地理解为右乘就是从右边乘进来,左乘就是从左边乘进来。
一比较,我们可以看出,pre其实执行的就是右乘的操作,而post执行的就是左乘的操作。
这是因为,在图像处理中,越靠近右边的矩阵越先执行,所以pre(也就是先的意思)所设置的矩阵T(Scale,Rotation也是一样的)就会先于其一开始设置的Scale执行,而post(后的意思)的因为是左乘,所以它会放在最左边,那么就会最后执行。
所以,上面三步的意思其实就是:
1)在当前的矩阵左边加一个Scale的操作,因为之前没有其的操作(reset了),那么当前的矩阵其实就只是 S 了。
2)在当前的矩阵(S)执行前,先执行一个平移到原点的操作(preTranslate),其实也就是进行右乘(S * T)。
3)在当前的矩阵(S * T)执行后,再执行一个从原点平移到中心点的操作(postTranslate),也就是进行一个左乘(-T * S * T)。
这就是Android中矩阵(Matrix)前乘和后乘所对应的图形学中矩阵中右乘和左乘的操作了。
不知道理解有没有错误,如有错误 ,希望有朋友能够指正,谢谢大家,另祝大家新年快乐!
下面是上一篇文章,关于图形学中矩阵和图形变换的关系,有兴趣的朋友也可以读一下:
2D平面中关于矩阵(Matrix)跟图形变换的讲解
分享到:
相关推荐
在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。计算C=AB总共需要p×q×r次乘法。 现在的问题是,...
给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1...确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。
Android中Matrix的简单用法,Matrix其实就是一个3*3的矩阵,利用这个矩阵对图像操作。在Android中,为我们提供一些封装好的方法可以进行一些简单的图像操作,总共分为rotate(旋转),scale(缩放),translate(平移)和...
矩阵链乘实验,实现矩阵链乘算法,n=23,24,25,…,28,矩阵大小为p0p1…pn,随机产生正整数,范围5-120
如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。 Input 输入包含多组测试数据。第一行为一个整数C,表示有C组测试数据,接下来有2*C行数据,每组测试数据占2行,每组测试...
android绘图中Matrix的使用
Android图片处理矩阵
定义一个二维方阵类 matrix。通过重载二元运算符“+”、“-”、“*”和一元运算符“~”, 来实现矩阵加、矩阵减、矩阵乘以及矩阵转置。
动态规划算法中矩阵连乘的实现代码,主要是用C语言编写;
自己编写的matrix矩阵类 可以实现矩阵的加减法、乘法、求逆 求逆采用lup算法
给定n个矩阵A1,A2,…,An,其中,Ai与Aj+1是可乘的,i=1,2,…,n-l。 你的任务是要确定矩阵连乘的运算次序,使计算这n个矩阵的连乘积A1A2…An时总的元素乘法次数达到最少。 例如:3个矩阵A1,A2,A3,阶分别为10...
essential matrix 本质矩阵essential matrix 本质矩阵essential matrix 本质矩阵
在Android中进行图像旋转需要使用Matrix,它包含了一个3*3的矩阵,专门用于进行图像变换匹配。Matrix ,中文里叫矩阵,高等数学里有介绍,在图像处理方面,主要是用于平面的缩放、平移、旋转等操作。Matrix没有机构...
这是一本很好的矩阵计算书,是研究数值计算方向的一本很好的工具书
Android-使用Matrix对Bitmap进行处理
每行为一组连乘矩阵的各维长度,行中第一个数字是连乘矩阵的个数n,n≤100,后面是n+1个维长。 矩阵个数为0表示输入结束。 Output 对每行输入,计算最优计算顺序,并以括号形式将计算表达式输出,各矩阵用A0, A1,...
Android Matrix 理论 应用详解 变换矩阵
【问题描述】使用动态规划算法解矩阵连乘问题,具体来说就是,依据其递归式自底向上的方式进行计算,在计算过程中,保存已子问题答案,每个子问题只解决一次,在后面计算需要时只要简单查一下得到其结果,从而避免...
矩阵链乘,输出最优全部加括号(matrix-Chain)
Android Matrix矩阵的使用及测试样例源码下载,定义一个等比例绽放的图像矩阵,并可以倾斜的矩阵。