3D"免费"三角测量相机

时间:2013-05-26 17:48:19

标签: java 3d camera trigonometry

我很抱歉,如果之前有人提出这个问题,我会进行搜索,但我找不到答案。

我的问题是,我希望在相机的X和Y旋转相关的所有3个轴上进行移动。

这就是我所做的:

private static void fly(int addX, int addY){ //parameters are the direction change relative to the current rotation

    float angleX = rotation.x + addX;   //angle is basically the direction, into which we will be moving(when moving forward this is always the same as our actual rotation, therefore addX and addY would be 0, 0)
    float angleY = rotation.y + addY;


    float speed = (moveSpeed * 0.0002f) * delta;
    float hypotenuse = speed; //the length that is SUPPOSED TO BE moved overall on all 3 axes


    /* Y-Z side*/
    //Hypotenuse, Adjacent and Opposite side lengths of a triangle on the Y-Z side
    //The point where the Hypotenuse and the Adjacent meet is where the player currently is.
    //OppYZ is the opposite of this triangle, which is the ammount that should be moved on the Y axis.
    //the Adjacent is not used, don't get confused by it. I just put it there, so it looks nicer.
    float HypYZ = speed;
    float AdjYZ = (float) (HypYZ * Math.cos(Math.toRadians(angleX))); //adjacent is on the Z axis
    float OppYZ = (float) (HypYZ * Math.sin(Math.toRadians(angleX))); //opposite is on the Y axis

    /* X-Z side*/
    //Side lengths of a triangle on the Y-Z side
    //The point where the Hypotenuse and the Adjacent meet is where the player currently is.
    float HypXZ = speed;
    float AdjXZ = (float) (HypXZ * Math.cos(Math.toRadians(angleY)));  //on X
    float OppXZ = (float) (HypXZ * Math.sin(Math.toRadians(angleY)));  //on Z

    position.x += AdjXZ;
    position.y += OppYZ;
    position.z += OppXZ;
}

我只在前进(参数:0,90)或向后(参数:180,270)时实现此方法,因为在横向移动时Y轴上不会发生移动,因为你不能在Z轴。 (横向移动的方法(扫射)工作得很好,所以我不会添加它。)

问题是,当我向上看90度或向下看90度然后向前移动时我应该只在Y轴上移动(垂直)但是由于某种原因我也向前移动(这意味着在Z上)轴,因为X轴是扫射)。

我确实意识到这种移动速度并不是一成不变的。如果你有解决方案,我也很乐意接受它。

1 个答案:

答案 0 :(得分:5)

我认为你的错误在于你没有完全投射你的距离(你的移动量hypothenuse)在水平面和垂直平面上。

换句话说,无论选择哪个方向,你现在正在做的是在水平面XZ中移动你的hypothenuse点,即使你已经移动了hypothenuse的一部分垂直方向Y。

您可能想要做的是将hypothenuse数量作为总数。

因此,您必须评估在水平平面中发生了多少运动以及在垂直轴上进行了多少运动。你的方向给你答案。

现在,我现在还不清楚你的两个角度代表什么。我强烈建议您在这种情况下使用Tait–Bryan angles(仅使用 yawn 音高,因为您似乎不需要滚动 - 你称之为Z旋转),以简化计算。

在此配置中,哈欠角明显与您对angleY的定义相似,而俯仰角则是水平面与hypothenuse矢量之间的角度(而不是角度)在YZ平面上的投影。

要阐明的架构:

Evaluation of the displacement given two angles

使用:

  • s从初始位置P_0P_1hypothenuse
  • 的移动量
  • a_y哈欠角和a_p投球
  • D_xD_yD_z每个轴的位移(将添加到position,即AdjXZOppYZ和{ {1}})

因此,如果您查看此表示,您可以看到X-Z中的三角形没有OppXZ作为斜边但是其投影s。对此距离的评估非常简单:如果您将自己置于三角形s_xz P_0 P_1中,则可以看到P_1xz。这给了你:

s_xz = s * cos(a_p)

至于float HypXZ = speed * Math.cos(Math.toRadians(angleP))); // s_xz float AdjXZ = (float) (HypXZ * Math.cos(Math.toRadians(angleY))); // D_x float OppXZ = (float) (HypXZ * Math.sin(Math.toRadians(angleY))); // D_z D_y,请再次将自己放在三角形OppYZ P_0 P_1中,然后您将获得:

P_1xz

现在,如果float OppYZ = (float) (speed * Math.sin(Math.toRadians(angleP))); // D_y 按照我的假设你实际上意味着提升的角度,那么代码中的angleXangleP = angleX

通过此更正,如果HypXZ = AdjYZangleX = 90,则

angleX = -90

...因此HypXZ = speed * cos(angleX) = speed * cos(90deg) = speed * 0; AdjXZ = 0。在水平面上没有移动。


注意:

要检查您的计算是否正确,您可以验证您是否确实移动了所需移动量的点(OppXZ = 0,即hypothenuse,即speed)。使用毕达哥拉斯定理:

s

根据上面给出的位移定义:

s² = s_xz² + D_z² // Applied in the triangle P_0 P_1 P_1xz
   = D_x² + D_y² + D_z² // Applied in the triangle P_0 P_1x P_1xz

希望它有所帮助......再见!