为大家带来包佬的分享~

随心所欲!使用矩阵转换不同坐标系 来自深夜小编 CG文章_CG资源

为大家带来包佬的分享~

为大家带来包佬的分享~



文/包小猩


距离上篇文章更新已经过去快两个月了,作为一个年更营销号(×),其实一直想更,但也没什么太好的想法。最近刚好在复习线性代数,看到矩阵变换时,想到之前有个不同空间坐标系转换问题,如果用矩阵来实现会更加简洁。故在此分享一波,希望各位能从中获取到自己想要的东西。


在阐述方法之前我先抛出一个问题:

如果现在有张图片,我想让左边的图片变成右边的结果,只提供旋转角度,目标位置和缩放信息,要怎么做?



可能你会说这个不是很简单嘛,用简单的缩放和位移,加减乘除都可以算出来。但是加减乘除第一不直观,其次做旋转的话比较麻烦。虽然可以用dot两个目标坐标系的单位轴来制作旋转,但是整个过程下来操作太多也不好整理。于是矩阵就成为解决此问题最直观的方法。


在推导这个矩阵之前,需要科普一下仿射变换:仿射变换是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。使用上我们一般采用齐次空间下的一个nxn矩阵下图是一个三维变换齐次空间下的4x4仿射变换矩阵。



其中红框部分的矩阵是做缩放变换操作的,蓝框部分的矩阵是做位移变换的。至于怎么用,咱们只需要把原始位置坐标和这个矩阵乘一下就可以得到矩阵变换之后的目标位置坐标。


但是现在我们只需要变换二维UV空间,所以可以压缩一个维度,使用3x3的仿射变换矩阵即可


然后咱们就可以开始推导了,现在我们先看看一个纯偏移和缩放的矩阵是什么样。需要什么参数:


需要变换的原始坐标位置                Position

需要变换原始坐标区域最大长宽      OriWH

需要变换原始坐标区域中心点         OriCenter

变换后坐标区域最大长宽                NewWH

变换后坐标区域中心点                   NewCenter


为了方便各位能直观搞懂这些东西都是啥,我在下图中标注了出来:



然后咱们可以考虑一下具体的计算顺序:


  1. 将uv原点挪到NewCenter并计算缩放和旋转

  2. 再将上述结果加上OriCenter偏移


可能你会好奇为什么要先NewCenter再OriCenter而不是反过来呢?其实我们可以将整个变换拆成两个部分来看。


第一部分是将图像uv原点挪到OriCenter

我们记这个变换为 A -> B


第二部分是将图像uv原点挪到NewCenter再缩放旋转(一般是先缩放再旋转,要是能确定是等比缩放其实可以无视这个顺序)

我们记这个变换为 A -> C


现在如果我们需要从B变换到C,那么其实就应该是A -> C的矩阵左乘A -> B矩阵的逆矩阵


了解这些之后,我们只需要列出所有需要使用到的矩阵即可(为了方便观察,我将所有操作的矩阵都先单独写,后面再整合到一起)



其中:

SM 是 Scale Matrix 缩放矩阵

OCM 是 Original Center Matrix 原始中心位移矩阵

NCM 是 New Center Matrix 目标中心位移矩阵

RM 是 Rotate Matrix 旋转矩阵 


接下来我们只需要按照 NCM -> SM -> RM -> OCM 的矩阵变换顺序应用到原始坐标上就可以得到目标效果


例如我这里让图片缩放到原来的四分之一,并且中心点围绕原始坐标中点做圆周运动,同时自身也有旋转。(注意所有的数据都应该是原始坐标系下的数据,不能说因为是目标点就定成目标坐标系的点,这样绝对是错误的)




接下来整理阶段我们只需要将这几个矩阵都合并一下,得到下面的结果:



可以看到内部有很多重复的运算,我们将重复的部分抽出来预先计算,可以得到以下结果:



这样在一定程度上减少了重复计算和多次矩阵乘法的消耗。


于是我们可以得到上面的那个变换效果了



可能看到这里大家还是有点懵:具体有什么用?能用在什么效果上?


其实在很多效果中都可以使用,比如将图片按照时间顺序叠在rt上可以模拟出很好看的效果:



简单效果就当是抛砖引玉了,肯定有更多用法 ~ 希望大佬们看完能有收获。


欢迎分享转发点击在看,你们的支持就是我更新的动力。


欢迎长按扫码加入交流QQ群:

加载中