5

在一个 Android 应用程序中,我想画一条奔跑的腿。要输出腿的上半部分,我会执行以下操作:

// legCX,legCY is the location on screen about which the leg rotates.
Matrix m = new Matrix();
m.postTranslate(-legCX,-legCY);
m.postRotate(legRot);
m.postTranslate(legCX,legCY);

然后我将矩阵设置到画布上并绘制腿。

如何画出膝盖以下腿的第二部分?它的旋转速度与其上方的腿不同,并且有一个中心点随上方的腿一起移动。我尝试了以下方法,但结果是最终结果是围绕某个不跟随上面腿的单点旋转。

Matrix m = new Matrix();
m.postTranslate(-legCX,-legCY);
m.postRotate(legRot);
m.postTranslate(0,-legLength);
m.postRotate(footRot);
m.postTranslate(0,legLength);
m.postTranslate(legCX,legCY);

我怀疑可能有必要在两个不同的 Matrix 对象中进行两次旋转,然后以某种方式将它们组合起来,但我不知道该怎么做。

编辑:这种类型的矩阵似乎被称为“变换矩阵”。组合多个操作称为转换的组合。然而,关于这个主题的页面都没有提到如何进行一系列的平移和旋转。

当然,如果您可以使用矩阵围绕一个点进行旋转,则必须可以以某种方式执行多个矩阵运算以允许围绕一个点进行旋转,然后围绕另一个点进行额外的旋转。

我曾尝试查看有关骨骼动画的页面,但我无法理解他们在谈论什么。

4

2 回答 2

6

如果我正确理解你的问题,你有一个相对旋转的情况。您可以尝试搜索双摆,见图。

双摆

使用旋转矩阵可以找到p1围绕点旋转的点的新坐标,例如p0

p2围绕点旋转的点的新坐标p1将是

最后,p2围绕点旋转的点的新坐标p0将是

矩阵乘法的顺序以及角度的符号也很重要。

于 2013-02-28T10:44:12.857 回答
2

恐怕这将与语言无关 - 我实际上正在 Android 中做类似的事情,但我正在学习 android 和矩阵数学!您似乎知道如何在 Android 中使用矩阵,所以我猜这不会有问题。

所以 - 假设我们有两个网格(其中一个网格是您可以独立绘制到屏幕上的东西):UpperLegLowerLeg.

  • 因为UpperLeg您将获得网格旋转的点(RotationPoint)(在现实世界中,我猜这将是臀部)并且您将获得LowerLeg连接到它的点(AttachmentPoint)(在现实世界中猜猜这将是膝盖)。
  • 因为LowerLeg您将获得网格旋转的点 ( RotationPoint)(在现实世界中,我猜这将是膝盖)。

UpperLeg.AttachmentPoint= LowerLeg.RotationPoint(这样你的腿就不会掉下来)。

现在让我们假设您有两种旋转量(一种用于UpperLeg,一种用于LowerLeg):UpperLeg.RotationLowerLeg.Rotation

(一个旋转的主题 - 如果你还没有听说过四元数,你应该看看 - 让我惊讶的是 1846 年的某个人想出了这些 - 它们基本上封装了旋转的概念,可以变成旋转矩阵,可以结合(通过乘法)并且不受万向节锁定的影响)。

首先你旋转UpperLeg

  1. 移动UpperLeg网格,使其UpperLeg.RotationPoint成为原点
  2. 旋转UpperLeg.Rotation
  3. 移动UpperLeg网格,使其位于现实世界中需要的位置。我看到你正在这样做。

所以LowerLeg它会是:

  1. 移动LowerLeg网格,使其LowerLeg.RotationPoint成为原点
  2. 旋转(UpperLeg.Rotation结合LowerLeg.Rotation
  3. 移动网格的量与步骤 3 中移动LowerLeg网格的量相同UpperLeg
  4. 将网格移动为由旋转LowerLeg的向量(从UpperLeg.RotationPoint到的向量) 。UpperLeg.AttachmentPointUpperLeg.Rotation

以上步骤可以组合优化。

本质上我是说:在需要
旋转LowerLeg时旋转,然后将其推到需要去的地方 - 它需要去的地方将取决于UpperLeg去的地方,以及你如何到达LowerLeg连接到的地方UpperLeg

这是我在这里的第一篇文章,所以如果我违反了任何基本规则,请告诉我它们是什么。

于 2013-03-02T20:30:48.470 回答