如何从偏航角计算方向矢量? [英] How to calculate direction vector from yaw angle?

查看:146
本文介绍了如何从偏航角计算方向矢量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,我不知道如何继续使用Java/LWJGL渲染OpenGL来计算方向向量.

I have an issue on where I do not know how to proceed on calculating a direction vector using Java/LWJGL to renderin OpenGL.

我有以下系统:

  • + X转到屏幕右侧
  • + Z进入我的屏幕
  • + Y转到屏幕顶部(海拔)

因此,我正在XZ平面上行走,现在我想实现/已经实现了WASD运动,并且它应该与我要走的当前方向有关. (W =朝相机的视线方向前进,S =向后等)

Therefore I am walking on the XZ plane, now I want to implement/have implemented WASD movement, and it should be related to the current direction I am going. (W = forward to camera look direction, S = backward, etc.)

我有一个偏航角角,定义如下:

I have a yaw angle that is defined as follows:

  • 直行时为0度
  • 向右90度
  • 后退180度
  • 向左倾斜270度

现在我只需要一个3D向量来表示 yaw 的方向,我该怎么做?

Now I simply want a 3D vector representing the direction of the yaw, how would I do that?

我正在使用以下Java代码(包括答案​​),但是似乎还有另一个错误:

I am using the following Java code, with the answer included, however it seems there is another bug:

@Override
protected void mouseMoved(final int dx, final int dy) {
    float yawDelta = dx / 10f;
    float pitchDelta = dy / 10f;
    yaw += yawDelta;
    pitch += pitchDelta;
    System.out.println("yaw = " + yaw);
    direction.updateZero().updateTranslate((float)Math.sin(Math.toRadians(yaw)), 0f, (float)Math.cos(Math.toRadians(yaw))).updateNormalized();
    System.out.println("direction = " + direction);
    updateView();
}

private void checkKeys() {
    if (isKeyCurrentlyDown(Keyboard.KEY_W)) {
        eye.updateTranslate(direction);
        updateView();
    }
    if (isKeyCurrentlyDown(Keyboard.KEY_S)) {
        eye.updateTranslate(direction.negated());
        updateView();
    }
    if (isKeyCurrentlyDown(Keyboard.KEY_A)) {
        eye.updateTranslate(direction.cross(Vector3f.Y.negated()));
        updateView();
    }
    if (isKeyCurrentlyDown(Keyboard.KEY_D)) {
        eye.updateTranslate(direction.cross(Vector3f.Y));
        updateView();
    }
    if (isKeyCurrentlyDown(Keyboard.KEY_Q)) {
        eye.updateTranslate(0.0f, -1.0f, 0.0f);
        updateView();
    }
    if (isKeyCurrentlyDown(Keyboard.KEY_Z)) {
        eye.updateTranslate(0.0f, 1.0f, 0.0f);
        updateView();
    }
}

private void updateView() {
    viewMatrix.identity().fpsView(eye, roll, yaw, pitch);
    Uniforms.setUniformMatrix4(UNIFORM_VIEW_MATRIX, false, viewMatrix);
}

随后

public Matrix4f fpsView(final Vector3f eye, final float rollAngle, final float yawAngle, final float pitchAngle) {
    //roll = rolling your head, Q&E
    //yaw = looking left/right, mouseY
    //pitch = looking up/down, mouseX
    float sinRoll = (float)Math.sin(Math.toRadians(rollAngle));
    float cosRoll = (float)Math.cos(Math.toRadians(rollAngle));
    float sinYaw = (float)Math.sin(Math.toRadians(yawAngle));
    float cosYaw = (float)Math.cos(Math.toRadians(yawAngle));
    float sinPitch = (float)Math.sin(Math.toRadians(pitchAngle));
    float cosPitch = (float)Math.cos(Math.toRadians(pitchAngle));

    //TODO cannot roll yet
    Vector3f xAxis = new Vector3f(
        cosYaw,
        -sinPitch * sinYaw,
        -cosPitch * sinYaw
    );
    Vector3f yAxis = new Vector3f(
        0.0f,
        cosPitch,
        -sinPitch
    );
    Vector3f zAxis = new Vector3f(
        sinYaw,
        sinPitch * cosYaw,
        cosPitch * cosYaw
    );

    return multiply(
        xAxis.getX(),               xAxis.getY(),               xAxis.getZ(),               0.0f,   //X column
        yAxis.getX(),               yAxis.getY(),               yAxis.getZ(),               0.0f,   //Y column  
        zAxis.getX(),               zAxis.getY(),               zAxis.getZ(),               0.0f,   //Z column
        0.0f,                       0.0f,                       0.0f,                       1.0f    //W column
    ).translate(eye);
}

以某种方式eye.updateTranslate()不起作用,它仅将操作数的值添加到eye坐标.我的逻辑那里有缺陷吗?

Somehow the eye.updateTranslate() is not working, which merely adds the values of the operand to the eye coordinate. Is any of my logic flawed there?

推荐答案

旋转部分比您要复杂的多.

The rotation portion is a bit more complicated than you have it.

 R = yawMat.pitchMat.rollMat 

其中:

    yawMat={ { cosZ, -sinZ, 0 }, { sinZ, cosZ , 0 }, {0,0,1 } };

    pitchMat =  { { cosY , 0 , sinY }, { 0, 1 , 0 }, { -sinY, 0, cosY } };

    rollMat = { {1,0,0 }, {0,cosX,-sinX }, {0,sinX,cosX } };

这三个点的积是构成齐次变换内的3x3旋转矩阵R的原因.点积的顺序确实很重要,因此请保持一致.

The dot product of the three is what makes up your 3x3 rotation matrix R inside the homogeneous transform. Order of the dot product does matter so keep it consistent.

此处是我的参考.

最终的4x4矩阵应为

T = {{R00,R01,R02,X},{R10,R11,R12,Y},{R20,R21,R22,Z},{0,0,0,1}}

编辑如果您想一次旋转一圈,那么其他两个3x3矩阵将移至同一位置,因此例如在偏航中仅旋转一圈即可.

Edit If you want to do one rotation at a time then the other two 3x3 matrices go to the identity so you would have for instance just a rotation in the yaw:

R = yawMat.I.I = yawMat

所以:

R = { { cosZ, -sinZ, 0 }, { sinZ, cosZ , 0 }, {0,0,1 } }

与其他人一样.

为构建转换矩阵而编写的内容应为:

As you have it written in order to build your transformation matrix it should be:

Vector3f xAxis = new Vector3f(
    cosYaw*cosPitch,
    cosYaw* sinPitch*sinRoll - sinYaw*cosRoll,
    cosYaw*sinPitch*cosRoll + sinYaw*sinRoll
);

Vector3f yAxis = new Vector3f(
    sinYaw*cosPitch,
    sinYaw*sinPitch*sinRoll + cosYaw*cosRoll,
    sinYaw*sinPitch*cosRoll - cosYaw*sinRoll
);
Vector3f zAxis = new Vector3f(
    -sinPitch,
    cosPitch*sinRoll,
    cosPitch * cosYaw
);

假设旋转顺序固定为x-> y-> z,然后平移X,Y,Z

Assuming fixed rotation order x -> y -> z followed by the translation X,Y,Z

这篇关于如何从偏航角计算方向矢量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆