Android中的Matrix(矩阵)

Android中的Matrix(矩阵)Android中的Matrix,了解如何使用Android的矩阵Matrix

大家好,又见面了,我是你们的朋友全栈君。

写在前面

看这篇笔记之前先看一下参考文章,这篇笔记没有系统的讲述矩阵和代码的东西,参考文章写的也有错误的地方,要辨证的看。

  1. 如何计算矩阵乘法
  2. android matrix 最全方法详解与进阶(完整篇)
  3. Android Matrix 最全方法详解与进阶
  4. 1-4 Canvas 对绘制的辅助 clipXXX() 和 Matrix

矩阵的乘法

比如有矩阵A和矩阵B,他们分别为:
v4-728px-multiply-matrices-step-2-version-3

可以看到A为2行3列的矩阵,B为3行2列的矩阵,矩阵乘法符合下面的规则:

  1. 只有A的列数和B的行数相等,A和B才可以做乘法
  2. A*B的结果C是2行2列的矩阵,行数等于A的行数,列数等于B的列数
  3. 结果矩阵C的第一行第一列数值为A的第一行和B的第一列中的数字分别相乘后再相加。其他行列结果依次类推
  4. 矩阵的乘法不满足交换律,即A*B != B*A
  5. 矩阵的乘法满足结合律M‘ = T*(M*R) = T*M*R = (T*M)*R

c

详细信息可以看这里:如何计算矩阵乘法

Android中常用的四种矩阵变换

Android中使用3×3的矩阵进行图形的变换,它看起来大概是下面这样:
20160518113919200

在Android中,使用一个3×1的矩阵来表示一个点:
xy1

x,y分别代表x,y轴上的坐标,而1代表屏幕在z轴上的坐标为默认的。如果将1变大,那么屏幕会拉远, 图形会变小。

平移(Translate)

20180611214717

图例:
005xtdi2jw1f6dqiw20xoj308c0dw0su

错切(Skew)

水平错切

20180611214828

图例:
005xtdi2jw1f6cniifb0sj308c0dw3yz

垂直错切

chuizhi

图例:
005xtdi2jw1f6cnkwyksij308c0dwq3f

复合错切

fuhe

图例:
005xtdi2jw1f6cqdu6olfj308c0dwdgi

旋转(Rotate)

xuanzhuan1

图例:
005xtdi2jw1f6cpp174twj308c0dwt8s

缩放(Scale)

suofang1

图例:
005xtdi2jw1f6cnk02zy9j308c0dwwej

Matrix的组合

应用矩阵进行图形变换的主要原因,是因为矩阵是可以通过矩阵的乘法进行组合使用的,如果想对canvas绘制的bitmap时,先平移T(dx, dy),再旋转R(θ),最后缩放S(k1,k2),就可以将三个变换矩阵相乘,M‘ = ABC,再对canvas应用M’矩阵即可。

Matrix的坐标系

矩阵的操作可以看作是以坐标原点为原点的坐标系在三维空间中做的变换,不同于canvas的屏幕坐标系坐标系,矩阵Matrix的坐标系为左手坐标系:

20160518114718678

这个坐标系对应的每个轴的旋转方向(从原点看出去,每个轴的旋转方向都是逆时针):

camaer

Matrix的操作可以看做是对上面左手坐标系的变换

因为Matrix变换后是对每个canvas的点起作用,其实也可以看做对这个三维坐标系起了作用,canvas绘制的是三维坐标系上的图像对canvas二位坐标系的投影。

所以,可以用自己的左手模拟进行平移旋转等操作,更加直观的想象变换后的效果。

Matrix的左乘和右乘

在Android中,有关矩阵的操作都是成对的,比如preTranslate(float dx, float dy)和postTranslate(float dx, float dy),通过看api的介绍,如果原矩阵为M,那么pre表示的是左乘,post表示右乘:

preTranslate : M’ = M * T(dx, dy) // 左乘
postTranslate: M’ = T(dx, dy) * M // 右乘

因为矩阵的变换是顺序执行的,所以在平时最常用的应该是pre左乘,所有的变换操作都依次执行,比如canvas常用的translate等变换方法其实就是左乘。右乘其实就是在所有操作之前增加一步操作,合理的运用右乘可以方便代码的编写。

比如:图形变换是以左边原点为原点的,所以旋转、缩放等功能应用到canvas.drawBitmap()方法时(因为bitmap常从原点往右下方画),图像表现出来的结果就特别奇怪,需要将canvas的坐标系移动到图像的中心点再操作然后再把坐标系移回去,那么如果只用pre左乘的话,代码是这样的:

Matrix matrix = new Matrix();
matrix.preTranslate(pivotX,pivotY);
// 各种操作,旋转,缩放,错切等,可以执行多次。
matrix.preTranslate(-pivotX, -pivotY);

如果合理使用右乘,那么代码就成了:

Matrix matrix = new Matrix();
// 各种操作,旋转,缩放,错切等,可以执行多次。
matrix.postTranslate(pivotX,pivotY);
matrix.preTranslate(-pivotX, -pivotY);

减少了postTranslate和preTranslate之间的距离。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155028.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Kali Linux 安装过程 超详细(图文并茂,通用版)

    Kali Linux 安装过程 超详细(图文并茂,通用版)从Kali2020.1版本新功能说起,在大致读过版本发布说明后,再进行安装,就不会有太大问题,不会频繁出错。然后给出了多种镜像下载途径,包括历史所有版本的镜像,供读者自行选择下载。最后开始正式安装,内容也是十分详细,图文并茂。在文章最后,介绍了默认安装的情况下,如果获取large版本,获取更多工具。最后介绍如何更新Kali,可升级至Kali2020.2版本。

    2022年6月4日
    72
  • .py和.ipynb的小知识

    .py和.ipynb的小知识目录1.相同点2.区别3.转换4.类比1.相同点用Python语言编写的源代码文件,其文件后缀是“.py”或“.ipynb”。用Python语言编写的源代码文件,其文件后缀是“.py”或“.ipynb”。2.区别.py:".py"文件是标准的Python源代码文件,通常情况下,使用“.py”的python源代码文件。可以用Spyder编辑并运行.py文件。也可…

    2025年8月10日
    2
  • 蒂森MC2服务器显示FC00,蒂森电梯MC2常用功能地址参数设置说明.pdf[通俗易懂]

    蒂森MC2服务器显示FC00,蒂森电梯MC2常用功能地址参数设置说明.pdf[通俗易懂]C1/12MC2A00TEXXXX–TS1.MC21.1.A000/F000A001/F0011.2.MF3/MF4/MS3A/BMP1MPMS31.3.//j1.4.1.5.A3001.6.1.7.1.8.C2/12MC2A00TEXXXX–TSA2C21MP1.71.9.1.10.C…

    2022年5月20日
    366
  • [转载]Matlab fmincon函数用法

    [转载]Matlab fmincon函数用法原文地址:fmincon函数用法”style=”text-decoration:none;color:rgb(151,38,38)”>Matlab fmincon函数用法作者:长笛人倚楼Gloria这个函数在之前优化工具箱一文中已经介绍过,由于其应用广泛,所以这里通过实例单独整理一下其用法。一、基本介绍求解问题的标准型为minF(X)s.tAXAeqX=

    2022年5月16日
    30
  • C++二维数组sort排序问题

    C++二维数组sort排序问题以往遇到行排列问题(按每行的字典序排序)的时候,总是使用结构体来进行排序,但是如何使用二维数组来达到同样的效果呢?实验内容:利用二维数组进行“三级排序”测试1:使用c++内置的普通型二维数组#include<algorithm>#include<iostream>usingnamespacestd;boolcmp(inta[],intb[]){ …

    2022年10月20日
    1
  • 头条社招Java岗位-面经

    头条社招Java岗位-面经

    2022年2月14日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号