3D libgdx 旋转

3D libgdx rotation

我认为这个问题不是重复的,或者如果是,我不明白如何让它工作。

(对不起,我的绘图能力太强了...)

我有一个球,半径为 0.5(因此,周长为 3.1415926)。 在每一帧中,我把它放在 oldPosition 中,我想把它放在 position 中,所以,沿着蓝色箭头方向移动,在图中用 v 向量表示。这很简单。

诀窍是我想让球在目标位置旋转。旋转轴应垂直于方向(绿色虚线),旋转应相对于物体中心进行(旋转将是平移长度的2倍)。

我的 libgdx 代码现在看起来像:

// During object initialization I have a Matrix4 with identify
Matrix4 rotation = new Matrix4();


// Now, this code during render()
Vector3 movement = position.sub(oldPosition);
float length = movement.len();

// drawing this on paper, it seems a correct way to compute orthogonal vector
rotation.rotateRad(new Vector3(-movement.z, 0f, movement.x), 2*length);

iSphere.transform = rotation.cpy().trn(position);

所以,基本上,我从识别 Matrix4 开始。在每一帧中,我对其应用旋转,在球体中应用该旋转,然后对其进行平移。

起初这似乎可行 (?),但经过多次旋转后,球开始向错误的方向旋转。

我尝试了使用四元数的实现,但也没有成功。应该是简单的东西我忘记了。

就像@Springrbua 说的那样,您可以使用叉积来让轴旋转。例如(未经测试的代码):

public void update(float delta) {
    velocity.add(tmpV.set(acceleration).scl(delta));
    position.add(tmpV.set(velocity).scl(delta));
    final float speed = velocity.len();
    final float angle = speed*delta*MathUtils.radiansToDegrees;
    Vector3 axis = tmpV.set(velocity).scl(-1f/speed).crs(Vector3.Y);
    tmpQ.set(axis, angle);
    rotation.mulLeft(tmpQ);
    transform.set(position, rotation);
}

这是一个工作示例的完整源代码:https://gist.github.com/xoppa/3b841fb52f46e8cdec24