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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • VUE(相关简介及初始)

    1.什么是vueVue是一个数据驱动页面的一个框架,基于MVVM模式,M指的是数据,V值得是视图,VM是视图模型,将数据绑定视图上(双向绑定)这个框架着重于VM部分2.VUE诞生的背景近几年来

    2022年3月29日
    40
  • cocos2d-x精灵移动的方法

    cocos2d-x精灵移动的方法

    2021年11月30日
    35
  • fsync函数

    fsync函数fsync函数,将文件数据同步到硬盘功能描述: 系统调用fsync将所有已写入文件描述符fd的数据真正的写道磁盘或者其他下层设备上。用法:#includeintfsync(intfd);#ifdef_POSIX_SYNCHRONIZ

    2022年5月31日
    131
  • Springboot集成RocketMQ

    Springboot集成RocketMQ什么是RocketMQ?官方说明:随着使用越来越多的队列和虚拟主题,ActiveMQIO模块遇到了瓶颈。我们尽力通过节流,断路器或降级来解决此问题,但效果不佳。因此,我们那时开始关注流行的消息传递解决方案Kafka。不幸的是,Kafka不能满足我们的要求,特别是在低延迟和高可靠性方面。看到这里可以很清楚的知道RcoketMQ是一款低延迟、高可靠、可伸缩、易于使用的消息中间件。具…

    2022年6月3日
    35
  • linux服务器,卸载tensorflow CPU 安装PGU版

    linux服务器,卸载tensorflow CPU 安装PGU版linux服务器,卸载tensorflowCPU安装PGU版写在前面之前用的和学习的都是pytorch框架,现在要运行一个keras的代码,得安装tensorflow和keras,按一个教程,直接在pycharm里setting,点那个+很快就装好了tensorflow和keras,运行了几次发现运行特别慢,用nvidia-smi查看,发现根本没有用pgu跑,一番查找,最后发现安装的tensorflow本身是按CPU跑的,要用GPU跑,得安装tensorflow-gpu。以下主要参考了https

    2022年6月22日
    48
  • Win10 锁屏图片路径/Win10 锁屏壁纸提取

    Win10 锁屏图片路径/Win10 锁屏壁纸提取

    2022年3月13日
    56

发表回复

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

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