如何Matrix.postScale(SX,SY,PX,PY)工作?工作、SX、postScale、Matrix

2023-09-09 21:09:51 作者:奶奶个北i

首先阅读 Taig的问题

Taig说:

当调用Matrix.postScale(SX,SY,PX,PY);矩阵变   缩放和又译(根据给定的点的x,y)。那   用于缩放成图像predestines这种方法,因为我   可以很容易地聚焦一个特定的点。   而Android文档介绍的方法是这样的:

When calling Matrix.postScale( sx, sy, px, py ); the matrix gets scaled and also translated (depending on the given point x, y). That predestines this method to be used for zooming into images because I can easily focus one specific point. The android doc describes the method like this:

Postconcats the matrix with the specified scale. M' = S(sx, sy, px, py) * M

     

乍一看,这似乎是荒谬的,因为M被认为是一个   3×3矩阵。周围挖我发现,Android的使用   4×4矩阵的计算(同时只能提供3×3在其API)。   由于这code是C语言编写的,我有一个困难时期试图   了解什么是真正发生的事情。

At a first glance this seems ridiculous because M is supposed to be a 3x3-Matrix. Digging around I've found out that android uses a 4x4-Matrix for its computations (while only providing 3x3 on its API). Since this code is written in C I'm having a hard time trying to understand what is actually happening.

我看到,在钨

我的问题是一样的Taig

My question is same as Taig

其实我想知道的:我如何申请缩放的这种   (有一个对焦点)来,我可以在访问3x3矩阵我   基于Java code?

What I actually want to know: How can I apply this kind of scaling (with a focused point) to the 3x3 Matrix that I can access within my Java-code?

谁能给我一个例子,2D缩放公式4个参数(SX,SY,PX,PY),一个10岁,孩子会理解?

Who can give me a example and 2d-scaling formula with 4 parameters (sx, sy, px, py) that a 10-year-old-kid would understand?

推荐答案

仔细看看矩阵的方法。你会看到的getValue()的setValue()。该文档称,他们有一个浮动阵列9价值的工作。也有一堆的常量: MSCALE_X MSCALE_Y MTRANS_X MTRANS_Y 等等,等等这些常数是指数进入浮法[9] 阵列。

Look more closely at the Matrix methods. You will see getValue() and setValue(). The docs say they work with a float array with 9 values. There are also a bunch of constants: MSCALE_X, MSCALE_Y, MTRANS_X, MTRANS_Y etc. etc. Those constants are indices into the float[9] array.

由于我们只工作2个维度,矩阵实际上是一个的 2×2 的矩阵。但因为这种基质支撑的仿射变换的,该矩阵扩展为一个3×3矩阵。 3×3 = 9,其对应于浮[9] 阵列。即,实质上,你的3×3矩阵。

Since we are only working in 2 dimensions, the matrix would actually be a 2x2 matrix. But because this matrix supports affine transforms, the matrix is extended to become a 3x3 matrix. 3x3 = 9, which corresponds to the float[9] array. That is, essentially, your 3x3 matrix.

矩阵的实际胆量是用C ++编写,并通过JNI访问,因为操作必须要快了快了快了快了快。他们甚至使用特种非标浮点数格式(16.16),它的运算速度进行了优化。

The actual guts of Matrix are written in C++ and accessed through JNI because the operations have to be fast fast fast fast fast. They even use a special non-standard floating point number format ("16.16") that is optimized for calculation speed.

我不知道你在哪里得到约4×4阵列的信息。下面是从C ++ JNI一个code片断:

I don't know where you are getting the information about a 4x4 array. Here's a code snippet from the C++ JNI:

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);
}

这是一个3×3矩阵的仿射变换。

It's a 3x3 matrix for an affine transform.

当你调用 matrix.postScale(),你正在修改的scaleX,的scaleY,transX和transY。 (该 pre ..()交...()方法preserve任何变换那是在你的矩阵开始)的矩阵应用新的变换是这样的:

When you call matrix.postScale(), you are modifying scaleX, scaleY, transX, and transY. (The pre..() and post...() methods preserve any transform that was in your matrix to start with.) The Matrix applies the new transform like this:


X' = X * scaleX + transX
Y' = Y * scaleY + transY

这就是整个矩阵乘法的简化版本。如果我有一个点(2,2),这个数字和我缩放2倍,新点为(4,4)。沿X或Y轴移动,我只加一个常数。

That's the simplified version of the entire matrix multiplication. If I have a figure with point (2,2) and I scale it 2x, the new point will be (4,4). To move along the X or Y axis, I just add a constant.

由于 Matrix.postScale()其实需要一个聚焦点,该方法在内部调整transX和放大器; transY好像你是在翻译,缩放,然后平移退了出去。这使得缩放出现像扩大/缩水围绕一点为中心的像素,吡

Because Matrix.postScale() actually takes a focus point, the method internally adjusts transX & transY as though you are translating in, scaling, then translating back out. This makes the scaling appear as though the expansion/shrinking is centered around a point px, py.


transX = (1 - scaleX) * px
transY = (1 - scaleY) * py

因此​​,对于焦点,我将身材(PX,PY)加入PX和PY直接到原来的X,Y值。然后,我做了扩展。但撤消的翻译,我要考虑到我原来的聚焦点的现在已经调整本身的,所以不是减去PX和PY,我必须减去的scaleX * PX和scaleY * PY。

So for the focus point, I move the figure to (px,py) by adding px and py directly to the original x,y values. Then I do the scaling. But to undo the translation, I have to take into account that my original focus point is now scaled itself, so instead of subtracting px and py, I have to subtract scaleX * px and scaleY * py.

斜或剪切的是像缩放但反对轴:

Skew or Shear is like scaling but with opposing axes:


X' = Y * skewX
Y' = X * skewY

既然你缩放和平移有无翘曲,如果skewX和skewY设置为零。因此,他们在矩阵乘法还在使用,他们只是不影响最终的结果。

Since you're scaling and translating without warping, skewX and skewY are set to zero. So they're still used in the matrix multiplication, they just don't affect the final outcome.

轮换的是由一个小触发补充完成的:

Rotation is done by adding in a little trig:


theta = angle of rotation
scaleX = cos(theta)
skewX = -sin(theta)
skewY = sin(theta)
scaleY = cos(theta)

再有就是 android.graphics.Camera (而不是 android.hardware.Camera ),可以拿一个2D平面旋转/翻译它在三维空间。这是 MPERSP_0 MPERSP_1 ,和放大器; MPERSP_2 开始发挥作用。我不会做这些方程;我是一个程序员,而不是一个数学家。

Then there is the android.graphics.Camera (as opposed to android.hardware.Camera) that can take a 2D plane and rotate/translate it in 3D space. This is where MPERSP_0, MPERSP_1, & MPERSP_2 come into play. I'm not doing those equations; I'm a programmer, not a mathematician.

不过,我并不需要成为一个数学家。我甚至都不需要知道如何矩阵执行其计算。我一直在努力,支持捏/变焦的ImageView的子类。所以,我用的是 ScaleGestureDetector 来告诉我,当用户缩放。它有方法 getScaleFactor() getFocusX() getFocusY()。我插入这些值转换成 matrix.postScale(),并用我的的ImageView 其设置为一个规模型 MATRIX ,我称之为 ImageView.setImageMatrix()我的缩放矩阵。瞧,图像缩放正是用户希望看到根据自己的手势的方式。

But I don't need to be a mathematician. I don't even need to know how Matrix does its calculations. I have been working on an ImageView subclass that supports pinch/zoom. So I use a ScaleGestureDetector to tell me when the user is zooming. It has methods getScaleFactor(), getFocusX() and getFocusY(). I plug those values into matrix.postScale(), and with my ImageView having a scale type set to MATRIX, I call ImageView.setImageMatrix() with my scaled matrix. Voilà, the image zooms exactly the way the user expects to see it based on their gestures.

所以,我不明白所有关于grokking如何矩阵作品引擎盖下的焦虑。不过,我希望这是我写到这里给你你正在寻找的答案。

So I don't understand all the angst about grokking how Matrix works under the hood. Still, I hope something I wrote here gives you the answers you are looking for.

P.S。如果有任何的真正的数学家正在读这篇文章,你可以请评论,并呼吁所有我做,所以我可以纠正他们的错误?谢谢你。

P.S. If any real mathematicians are reading this, could you please comment and call out all the mistakes I made so I can correct them? Thanks.