How to calculate direction vector from yaw angle?

冷暖自知 提交于 2020-01-02 07:08:02

问题


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

I have the following system:

  • +X goes to the right of the screen
  • +Z goes into my screen
  • +Y goes to the top of the screen (altitude)

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 degrees if going straight forward
  • 90 degrees if going to the right
  • 180 degrees if turning back
  • 270 degrees if going to the left

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

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();
}

and

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();
    }
}

and

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

and subsequently

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);
}

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?


回答1:


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

 R = yawMat.pitchMat.rollMat 

where:

    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 } };

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.

Here is my reference.

Final 4x4 matrix should look like

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

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

So:

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

Likewise for the others.

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
);

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




回答2:


y is always 0

x=sin (yaw)
z=cos (yaw)



来源:https://stackoverflow.com/questions/21239386/how-to-calculate-direction-vector-from-yaw-angle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!