簡體   English   中英

如何從偏航角計算方向矢量?

[英]How to calculate direction vector from yaw angle?

我有一個問題,我不知道如何繼續使用Java / LWJGL計算方向向量來渲染OpenGL。

我有以下系統:

  • + X出現在屏幕右側
  • + Z進入我的屏幕
  • + Y到屏幕頂部(海拔高度)

因此,我正在XZ飛機上行走,現在我想實施/實施WASD運動,它應該與我目前的方向有關。 (W =前進到攝像機視線方向,S =后退等)

我的偏航角定義如下:

  • 如果直接向前0度
  • 如果向右走90度
  • 轉回180度
  • 如果向左轉270度

現在我只想要一個代表偏航方向的3D矢量,我該怎么做?

我使用以下Java代碼,包括答案,但似乎還有另一個錯誤:

@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坐標。 我的邏輯是否存在缺陷?

y始終為0

x =罪(偏航)
z = cos(偏航)

旋轉部分比你有點復雜。

 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的組成部分。 點積的順序很重要,所以要保持一致。

是我的參考。

最終的4x4矩陣看起來應該是這樣的

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

編輯如果您想一次進行一次旋轉,那么另外兩個3x3矩陣將轉到標識,因此您可以在偏航中進行旋轉:

R = yawMat.I.I = yawMat

所以:

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

對其他人也一樣。

正如您為了構建轉換矩陣而編寫的那樣,它應該是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM