找不到角度物体在弧度上移动

时间:2014-08-26 02:16:43

标签: javascript math sin degrees radians

我一直在制作一款名为Minecraft PE的游戏,我正在用它来学习。在我展示代码之前,我想让您知道Y是纵轴,XZ是水平的。这是我使用的一些代码:

Math.asin(Math.sin((fPosXBeforeMoved - sPosX) /
Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) + 
Math.pow(fPosZBeforeMoved - sPosZ, 2))));

我没有使用tan,因为有时会以某个角度返回NaN之类的内容。当我清楚地使用Math.asin时,这段代码给了我们角度的正弦。 angle是介于-1和1之间的值,它可以正常工作!我知道它有效,因为当我经过Z轴时,我期待并且它确实从负变为正。但是,我认为它应该返回弧度?我读到某处输入是弧度,但我的输入不是弧度。我真的想要回答我自己的代码如何工作以及我应该如何做到这一点!我花了一整天学习三角学,但我真的很沮丧,所以现在我问问我从哪里得到我的答案!

有人可以解释我自己的代码是如何工作的,以及我应该如何修改它以获得弧度的角度?我做得对吗?我实际上给它弧度,然后把它变成某种正弦度类型的东西吗?

1 个答案:

答案 0 :(得分:3)

好的,让我们快速回顾sinasin是什么。看看下图中的这个直角三角形:

来源:Wikipedia

通过查看此直角三角形的点A,我们可以看到线段ACAB之间形成了一个角度。该角度与sin之间的关系是sin是相对边长度与斜边的长度之比。换句话说:

sin A = opposite / hypotenuse = a / h

这意味着,如果我们选择a / h,则等于位于sin的角度的A。因此,要找到实际角度,我们需要在此等式的两边应用正弦算子。就这样:

A = asin(a / h)

例如,如果我们的三角形中有a = 1h = 2,则此右三角形在ACAB之间的角度正弦为:

sin A = 1 / 2

要找到此处的实际角度,我们会这样做:

A = asin(1 / 2)

把它放在你的计算器中,我们得到30度。弧度是表示角度的另一种方式,其中包含以下关系:

angle_in_radians = (angle_in_degrees) * (Math.PI / 180.0)

我实际上对您的代码感到困惑,因为您之后正在asin然后sinasinsin之间的属性为:

arcsinasin相同。上面的等式表明只要x >= -Math.PI / 2, x <= Math.PI / 2x >= -90, x <= 90度,那么这种关系就成立了。在您的代码中,sin内的参数肯定介于-1到1之间,因此实际上简化为:

(fPosXBeforeMoved - sPosX) / Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) + 
Math.pow(fPosZBeforeMoved - sPosZ, 2));

如果要查找移动点之间的角度,则不要使用三角形的右侧。我稍后会详细介绍。


好的,那么这与你的问题有何关系?看一下代码中的等式。我们有四点需要看一下:

  • fPosXBeforeMoved - 我们移动之前您的观点的X位置
  • sPosX - 我们移动后您的观点的X位置
  • fPosZBeforeMoved - 我们移动之前您的观点的Z位置
  • sPosZ - 我们移动后你的观点的Z位置。

我们实际上可以在这样的直角三角形中表示这一点(原谅不好的图表):

enter image description here

我们可以代表您在(fPosXBeforeMoved,fPosZBeforeMoved)平面上移动XZ之前的点,而(sPosX,sPosZ)就是您移动之后的点。在此图中,X将是水平组件,而Z将是垂直组件。想象一下,你正在你面前拍照。 X将是从左到右的轴,Z将是向上和向下的轴,Y将是朝向您的轴并进入图片内部。

我们可以通过取AC坐标和相对(X)段的长度之间的差异来找到相邻(AB)段的长度Z坐标之间的差异。我们剩下的就是找到斜边的长度(h)。如果你从学校回忆起来,这只是通过使用毕达哥拉斯定理来完成的:

h^2 = a^2 + b^2
h = sqrt(a^2 + b^2)

因此,如果您参考图表,我们的斜边因此(在JavaScript中):

Math.sqrt(Math.pow(fPosXBeforeMoved - sPosX, 2) + Math.pow(fPosZBeforeMoved - sPosZ, 2));

您会将此识别为代码的一部分。我们介绍了sin,但让我们来看看coscos是相邻边长于斜边的长度比。换句话说:

cos A = adjacent / hypotenuse = b / h

这解释了这一部分:

(sPosX - fPosXBeforeMoved) / Math.sqrt(Math.pow(sPosX - fPosXBeforeMoved, 2) + 
Math.pow(sPosZ - fPosZBeforeMoved, 2));

请注意,我交换减去sPosXfPosXBeforeMoved与您之前的代码相比。原因是因为当您检查之前和之后的点,总是先到之后的点,那么之前的点是第二个。在你计算斜边的底部,这并不重要,因为无论从哪个顺序减去数值,我们都取减法的平方,所以无论如何你都会得到相同的数字。订购。我决定在斜边交换订单,以保持一致。订单确实在顶部很重要,因为当您进行减法时,正值或负数值会在您最终找到角度时产生影响。

请注意,此除法始终介于-1到1之间,因此我们当然可以使用反三角函数。最后,如果要查找角度,则应用反余弦。换句话说:

Math.acos((sPosX - fPosXBeforeMoved) / Math.sqrt(Math.pow(sPosX - fPosXBeforeMoved, 2)
+ Math.pow(sPosZ - fPosZBeforeMoved, 2)));

这就是我认为你应该编程的东西。请注意,这将返回角度以弧度。如果您在度数中喜欢这个,那么请使用我在上面显示的等式,但重新排列它以便您解决度数而不是弧度。就这样:

angle_in_degrees = angle_in_radians * (180.0 / Math.PI)

至于你现在拥有的东西,我怀疑你只是测量相邻和斜边的比例,如果你想检测你在每个轴上的交叉点,那就完全没问题了。如果你想找到实际的角度,我会改用上面的代码。


祝你好运,玩得开心!