使用四元数控制球体周围的对象

时间:2015-01-06 22:02:17

标签: javascript rotation three.js quaternions

在我的游戏中,用户控制飞机(从顶部看),飞越地球(Sphere对象)。飞机可以向左或向右旋转(转向)(通过按下左或右箭头键),按下向上箭头键可以加速。因此,飞机总是具有基于用户输入的方向(旋转)和特定速度(速度),存储在vx和amp; vy变量。

在渲染循环中,vx& vy变量用于旋转地球。所以飞机实际上并没有移动,飞机下方的地球旋转会给飞机飞越地球的印象。

这一切都很棒,直到玩家用他的飞机“到达”地球的另一边。现在,当用户飞到屏幕的“右侧”时,地球也向右旋转,这使得飞机看起来向后飞。问题来自于尝试将我之前飞机游戏的一些旧2D代码融入到这个3D游戏中。

我想知道如何用四元数来解决这个问题。我确信我需要那些,但我完全不理解它们。我认为我的vx和vy变量对此仍然有用,因为它们可以制作某种“新位置”向量。从我读到的是我应该规范化矢量,获得轴和角度,但我不知道如何获得这些。任何帮助将不胜感激!


以下是用户在某个x / y方向飞行时旋转地球的代码加上图像,以便更好地了解游戏情况。

// AIRPLANE VARS
var friction = 0.85;
var vr = 7.5; // Rotate-velocity
var thrust = 0.5;
var max_speed = 20;
var vx = 0; // X-velocity
var vy = 0; // Y-velocity

// RENDER LOOP
function render() {

    // check states

    if (rotate_left) {
        player.rotation.y = player.rotation.y + (vr * (Math.PI / 180));
    } else if (rotate_right) {
        player.rotation.y = player.rotation.y - (vr * (Math.PI / 180));
    }

    if(throttle){
        //var radians = ((player.rotation.y * Math.PI) / 180);
        var radians = player.rotation.y;
        var ax = (Math.cos(radians) * thrust);
        var ay = (Math.sin(radians) * thrust);

        vx = vx + ax;
        vy = vy + ay;
    } else {
        //ship.gotoAndStop(1);
        vx = vx * friction;
        vy = vy * friction;
    }

    // rotate the globe in the opposite direction of the airplane movement
    globe.rotation.x = globe.rotation.x - (-vx/100);
    globe.rotation.y = globe.rotation.y - (vy/100);
}

simple explanation of the game

1 个答案:

答案 0 :(得分:0)

我不熟悉您的实施框架,它从您的代码中显示为three.js。看到“转弯”控件如何影响播放器也有点困难,因为你没有提到如何定义平面的轴。我可能没什么帮助,但我可以给你一些启动技巧。

首先familiarise yourself具有四元数和the implementation of it in three.js的结构。 在许多文本中,它们显示为q = [w,x,y,z],然而它们似乎在三个.js中它们被定义为q = [x,y,z,w]。不要过分担心这些数字是什么,因为它们非常违反直觉。

有几种方法可以根据速度旋转四元数。

我认为这是你最好的镜头:通过使用给定here的导数方程,通过计算绕地球的平面(以及平面周围的地球)的角速度来旋转四元数。这是由3D particle equation here给出的。您可以将时间缩放的导数(dt * dqdt)添加到四元数q,然后将其重新正规化以便为旋转设置动画。

另一种方法是选择要结束的四元数旋转,并使用slerp操作(内置于three.js)。

如果您向我提供有关如何定义球体,平面和全局帧的更多详细信息,我可以提供更多帮助。