【问题标题】:Android. How to move object in the direction it is facing (using Vector3 and Quaternion)安卓。如何沿它所面对的方向移动对象(使用 Vector3 和四元数)
【发布时间】:2013-08-28 10:50:49
【问题描述】:

我正在使用 libGDX(实际上对它来说很新)和 Android。我想将 3d 对象朝它所面对的方向移动(使用一些速度)。我认为这是一个基本问题,但找不到直接的答案。我有一个表示对象旋转(方向)的四元数,我有一个表示对象位置的 Vector3。问题是如何使用来自四元数的信息更新位置 Vector3 以便在四元数表示的方向上移动对象。 (另一种方法是从四元数中提取滚动俯仰和偏航,并通过应用三角计算获得新的坐标。但我认为必须有一种方法可以使用 Vector3 和 Quat 来实现这一点。)

【问题讨论】:

    标签: java android opengl-es libgdx


    【解决方案1】:

    四元数用于指定旋转。您首先需要指定不应用旋转时的方向。例如,如果您想在未应用旋转时沿 X 轴移动:

    Vector3 baseDirection = new Vector3(1,0,0);
    

    确保基准方向是规范化的(长度=1),可以使用nor()方法来保证安全:

    Vector3 baseDirection = new Vector3(1,0,0).nor();
    

    接下来您需要使用四元数旋转方向:

    Vector3 direction = new Vector3();
    Quaternion rotation = your_quaternion;
    direction.set(baseDirection);
    direction.mul(rotation);
    

    现在你有了方向,你可以用你想移动的量来缩放它。您可能希望每帧都执行此操作,具体取决于自上一帧以来经过的时间。

    final float speed = 5f; // 5 units per second
    Vector3 translation = new Vector3();
    translation.set(direction);
    translation.scl(speed * Gdx.graphics.getDeltaTime());
    

    最后你需要将翻译添加到位置

    position.add(translation);
    

    当然,根据您的实际实现,您可以批处理多个操作,例如:

    translation.set(baseDirection).mul(rotation).scl(speed * Gdx.graphics.getDeltaTime());
    position.add(translation);
    

    更新: 从 Xoppa 的评论中添加工作代码:

    translation.set(baseDirection).rot(modelInstance.transform).nor().scl(speed * delta)
    

    【讨论】:

    • 嗨,Xoppa!谢谢你的回答。它看起来像我一直在寻找的东西。但不幸的是,它没有按预期工作。我按原样使用了您的代码,但得到了奇怪的结果。我的对象开始向右(X 轴)。然后我将它绕 Z 轴旋转 35 度。物体看起来有点向上。我应用您的代码并期望对象向右和向上移动。但它向右移动,到顶部的位移很小。 35 度应该给出 dY/dX=0.7 (tan(35))。你能帮忙吗?
    • 你好,Xoppa。经过一番调查,我觉得我得到的四元数有问题。我在 Rajawali(3d 引擎)中创建了相同的场景。将对象旋转相同的 35 度。并将他们的四元数与您的代码一起使用。它就像一个魅力。 dY/dX = 0.7。完美无瑕。所以答案是正确的。但是我从 libgdx 得到的四元数是错误的(与有效的值相比错误的值(来自 Rajawali))。我得到它使用:modelInstance.transform.getRotation(quaternion)。这是正确的方法吗?
    • 您的模型实例是否已缩放? iirc 您可以使用 Matrix4 直接旋转 Vector3,因此您可以跳过四元数 direction.set(baseDirection).rotate(modelInstance.transform).nor()。或者,如果您使用的是后一种方法:translation.set(baseDirection).rotate(modelInstance.transform).nor().scl(speed * delta)。请注意,我不确定rotate() 方法,它可能被称为rot()(但不是mul())。
    • 嗨,Xoppa!谢谢!它就像一个魅力!:) 顺便感谢您的教程。真的帮助我开始使用 lidgdx
    猜你喜欢
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2017-03-22
    • 2018-07-27
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多