Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从偏航角计算方向矢量?_Java_Opengl_Math_Lwjgl - Fatal编程技术网

Java 如何从偏航角计算方向矢量?

Java 如何从偏航角计算方向矢量?,java,opengl,math,lwjgl,Java,Opengl,Math,Lwjgl,我有一个问题,我不知道如何继续使用Java/LWJGL来计算OpenGL中的方向向量 我有以下系统: +X在屏幕的右边 +Z进入我的屏幕 +Y进入屏幕顶部(高度) 因此,我在XZ平面上行走,现在我想要实现/已经实现WASD运动,它应该与我要去的当前方向相关。(W=向前至摄像机观察方向,S=向后等) 我有一个偏航角,定义如下: 如果一直向前,则为0度 向右转90度 如果掉头180度 向左转270度 现在我只需要一个代表偏航方向的3D矢量,我该怎么做 我正在使用以下Java代码,包括答案,但

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

我有以下系统:

  • +X在屏幕的右边
  • +Z进入我的屏幕
  • +Y进入屏幕顶部(高度)
因此,我在XZ平面上行走,现在我想要实现/已经实现WASD运动,它应该与我要去的当前方向相关。(W=向前至摄像机观察方向,S=向后等)

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

  • 如果一直向前,则为0度
  • 向右转90度
  • 如果掉头180度
  • 向左转270度
现在我只需要一个代表偏航方向的3D矢量,我该怎么做

我正在使用以下Java代码,包括答案,但似乎还有另一个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();
}

然后

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=sin(偏航)

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
因此:

其他人也是如此

正如您为构建转换矩阵而编写的,它应该是:

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

我已经认为应该是这样,然而,这意味着在我的应用程序的其他地方我有一个bug。我已经用出现问题的代码更新了问题。再次确认
偏航
方向
完全腐蚀。你第二次问这个问题,得到了与我发布的非常相似的答案。。。。我认为使用一个复合矩阵的整个想法是,你可以在一个步骤中完成所有工作。在构造旋转矩阵并将其放入齐次变换矩阵后,你确实有一个矩阵T。你可以通过计算来避免点积,但是如果你先取三个的点积,它的可读性会更好。起初我不理解答案,但是在阅读了其他答案和其他几个主题后,我终于明白了发生了什么。
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
);