更仔细地查看 Matrix 方法。您将看到getValue() 和setValue()。文档说他们使用具有 9 个值的 float 数组。还有一堆常量:MSCALE_X、MSCALE_Y、MTRANS_X、MTRANS_Y 等等。这些常量是 float[9] 数组的索引。
因为我们只在二维中工作,所以矩阵实际上是一个 2x2 矩阵。但是因为这个矩阵支持仿射变换,所以矩阵被扩展为一个 3x3 矩阵。 3x3 = 9,对应于float[9] 数组。也就是说,本质上是您的 3x3 矩阵。
Matrix 的实际内容是用 C++ 编写并通过 JNI 访问的,因为操作必须快速快速快速快速快速。他们甚至使用针对计算速度进行了优化的特殊非标准浮点数格式(“16.16”)。
我不知道您从哪里获得有关 4x4 阵列的信息。这是来自 C++ JNI 的代码 sn-p:
SkScalar fMat[9];
mutable uint32_t fTypeMask;
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) {
fMat[kMScaleX] = sx;
fMat[kMSkewX] = 0;
fMat[kMTransX] = tx;
fMat[kMSkewY] = 0;
fMat[kMScaleY] = sy;
fMat[kMTransY] = ty;
fMat[kMPersp0] = 0;
fMat[kMPersp1] = 0;
fMat[kMPersp2] = 1;
unsigned mask = 0;
if (sx != 1 || sy != 1) {
mask |= kScale_Mask;
}
if (tx || ty) {
mask |= kTranslate_Mask;
}
this->setTypeMask(mask | kRectStaysRect_Mask);
}
这是一个用于仿射变换的 3x3 矩阵。
当您调用matrix.postScale() 时,您正在修改 scaleX、scaleY、transX 和 transY。 (pre..() 和 post...() 方法会保留矩阵中的所有转换。)Matrix 应用新的转换,如下所示:
X' = X * scaleX + transX
Y' = Y * scaleY + transY
这是整个矩阵乘法的简化版本。如果我有一个带有点 (2,2) 的图形并将其缩放 2 倍,则新点将是 (4,4)。要沿 X 或 Y 轴移动,我只需添加一个常量。
因为Matrix.postScale() 实际上需要一个焦点,所以该方法在内部调整 transX 和 transY,就好像您正在平移、缩放、然后平移回来一样。这使得缩放看起来好像扩展/收缩以点 px, py 为中心。
transX = (1 - scaleX) * px
transY = (1 - scaleY) * py
所以对于焦点,我通过将 px 和 py 直接添加到原始 x,y 值来将图形移动到 (px,py)。然后我进行缩放。但要撤消翻译,我必须考虑到我原来的焦点现在自己缩放,所以我必须减去 scaleX * px 和 scaleY * py,而不是减去 px 和 py。
Skew 或 Shear 类似于缩放但具有相反的轴:
X' = Y * skewX
Y' = X * 偏斜Y
由于您在没有变形的情况下进行缩放和平移,因此将 skewX 和 skewY 设置为零。所以它们仍然在矩阵乘法中使用,它们只是不影响最终结果。
旋转是通过添加一个小三角来完成的:
theta = 旋转角度
scaleX = cos(θ)
skewX = -sin(θ)
skewY = sin(theta)
scaleY = cos(θ)
然后是android.graphics.Camera(相对于android.hardware.Camera)可以采用2D 平面并在3D 空间中旋转/平移它。这就是MPERSP_0、MPERSP_1 和MPERSP_2 发挥作用的地方。我不是在做那些方程式;我是程序员,不是数学家。
但我不需要成为一名数学家。我什至不需要知道Matrix 是如何计算的。我一直在研究支持捏合/缩放的 ImageView 子类。所以我使用ScaleGestureDetector 告诉我用户何时缩放。它有方法getScaleFactor()、getFocusX() 和getFocusY()。我将这些值插入matrix.postScale(),并且我的ImageView 的比例类型设置为MATRIX,我用我的比例矩阵调用ImageView.setImageMatrix()。瞧,图像会根据用户的手势完全按照用户期望的方式缩放。
所以我不明白所有关于探索Matrix 如何在幕后工作的焦虑。不过,我希望我在这里写的东西能给你你正在寻找的答案。