【问题标题】:Rotation of the translational component of a Matrix矩阵平移分量的旋转
【发布时间】:2023-03-28 03:07:01
【问题描述】:

使用 android.graphics.Matrix 库:

Matrix foo = new Matrix();

foo.setTranslate(10.0f, 0.0f);
Log.d("MatrixTest", foo.toString());

foo.postRotate(30.0f, 0.0f, 0.0f);
Log.d("MatrixTest", foo.toString());

我得到以下输出:

foo = {[1.0, 0.0, 10.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}
foo = {[0.8660254, -0.5, 8.660254][0.5, 0.8660254, 5.0][0.0, 0.0, 1.0]}

这正是我所期望的。

现在我的应用程序也可以在桌面上运行很有用,所以我正在移植到 libgdx。

使用 com.badlogic.gdx.math.Matrix3 库:

Matrix3 bar = new Matrix3();

bar.translate(10.0f, 0.0f);
System.out.println(bar.toString());

bar.rotate(30.0f);
System.out.println(bar.toString());

我得到以下输出:

bar = [1.0|0.0|10.0] [0.0|1.0|0.0] [0.0|0.0|1.0]
bar = [0.8660254|-0.5|10.0] [0.5|0.8660254|0.0] [0.0|0.0|1.0]

在这种情况下,X 的平移分量没有被旋转。

这是正确的行为吗? android postRotate() 方法和 libgdx rotate() 方法的 API 将它们描述为 post-rotate 函数。

对于 libgdx Matrix4,我得到了类似的结果,这是我真正想要使用的。

有人可以提出一个很好的方法来重现使用 libgdx Matrix3 或 4 从 android 库获得的结果吗?

【问题讨论】:

  • 我认为交换操作应该可以满足您的需求。所以先旋转再平移。如果是这种情况,我将在答案中更详细地解释。
  • 你当然是对的。我知道矩阵乘法不是可交换的。但是由于这两个 API 都宣传自己是 postMultiply,令人沮丧的是它们不会产生相同的结果!
  • 好吧,第二个似乎使用标准操作,因此文档错误或解释错误。
  • 我的理解有误,我很困惑哪个矩阵是后级联的。谢谢。

标签: java android matrix opengl-es rotational-matrices


【解决方案1】:

只是为了弄清楚...

如果你只坚持矩阵乘法然后尝试使用方便的方法来使用矩阵本身的运算,那么它是最不模糊的。

在大多数情况下,当对矩阵进行诸如平移之类的操作时,将创建一个平移矩阵,并将原始矩阵乘以新矩阵,即originalMatrix*translationMatrix。这就是您的第二个示例中发生的情况。你的第一个例子有一个前缀“post”,它似乎做了逆运算translationMatrix*originalMatrix

我可以理解这个“帖子”可能很有用,对于不太熟悉矩阵运算的人来说,它甚至可能更自然地使用。我无法理解的是“postMultiply”。这根本不是它的工作方式,这不是矩阵乘法的使用方式,只会让大多数开发人员感到困惑。不仅在学习过程中,即使以后有人会阅读此代码。当然可以,但对我来说这和写这样的东西是一样的:

先打印N整数值:

    for(int i=N; i>0; --i)
    {
        int printValue = N-i+1;
        // print the printValue
    }

当然可以,但对我来说完全不可读。

如果在任何情况下您都无法想象矩阵乘法,那么您应该将其视为从第一人称看它。例如,在 X 轴上平移意味着向前走,Y 向左和 Z 向上。旋转只会围绕您的中心进行,不会影响您的位置。

所以在第一个示例中,您首先向左旋转 30 度,然后您现在面向点 (0.8660254, 0.5)。然后你沿着 X 轴平移 10,这意味着向前走 10 点,你的位置变成(0.8660254, 0.5)*10.0,所以你最终在(8.660254, 5.0) 面对(8.660254 + 0.8660254, 5.0 + 0.5)

在第二个示例中,您首先沿 X 轴平移 10 个点,这意味着向前移动 10 个点,在 (10, 0) 结束时仍然面向相同的方向,然后向左旋转 30 度并最终以相同的方向结束位于(10.0, .0),面向(10.0+0.8660254, .0+.5)

正如您现在可能从结果中看到的那样,您正在获取矩阵中的列(而不是您的情况下的行)定义矩阵基向量。因此,只需从这些向量中,您就可以了解对象面向的方向以及它的中心在哪里。您也可以简单地从这些向量构造一个矩阵。如果您想为位置为P 并面向D 方向的对象创建矩阵,则矩阵为:

D.x, D.y, .0
-D.y, D.x, .0
P.x, P.y, 1.0

在你的情况下转置

D.x, -D.y, P.x
D.y, D.x, P.y
.0, .0, 1.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 2011-01-25
    • 2013-12-06
    • 1970-01-01
    • 2012-08-11
    • 2012-09-09
    相关资源
    最近更新 更多