3

我一直在为一款名为 Minecraft PE 的游戏制作模组,并且正在使用它来学习。在我展示我的代码之前,我想让你知道它Y是垂直轴X并且Z是水平的。这是我使用的一些代码:

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

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

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

4

1 回答 1

3

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

资料来源:维基百科

通过查看A这个直角三角形的点,我们看到线段AC和之间形成了一个角度AB。这个角度和之间的关系sinsin对边的长度与斜边的比值。换句话说:

sin A = opposite / hypotenuse = a / h

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

A = asin(a / h)

例如,如果a = 1h = 2在我们的三角形中,这个直角三角形在AC和之间形成的角的正弦AB是:

sin A = 1 / 2

为了找到这里的实际角度,我们这样做:

A = asin(1 / 2)

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

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

我实际上对你的代码有点困惑,因为你正在做asin然后sin之后。asin和之间的属性sin是:

arcsin是一样的asin。上述等式表明,只要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我们移动后您的点的位置。

我们实际上可以像这样用直角三角形来表示它(请原谅坏图):

在此处输入图像描述

我们可以将您移动之前的点表示为(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)

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


祝好运并玩得开心点!

于 2014-08-26T03:30:29.463 回答