【问题标题】:Can't find the angle object is moving in radians找不到角度对象以弧度移动
【发布时间】:2014-10-19 06:14:31
【问题描述】:

我一直在为一款名为 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 轴时,它确实从负转换为正。但是,我认为它应该返回弧度?我在某处读到输入是弧度,但我的输入不是弧度。我真的很想知道我自己的代码是如何工作的以及我应该如何做的!我花了一整天时间学习三角学,但我真的很沮丧,所以现在我问我从哪里得到所有答案的问题!

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

【问题讨论】:

  • 欢迎来到 StackOverflow!很高兴看到年轻的爱好者这么早就参与到编程中来了 :) 这就是我真正想说的,除了你好。我将编辑您的帖子以进行格式化,然后我将尝试回答您的问题。敬请期待!

标签: javascript math trigonometry degrees radians


【解决方案1】:

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

来源:Wikipedia

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

sin A = opposite / hypotenuse = a / h

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

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 位置。

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

我们可以在XZ 平面上将您移动之前的点表示为(fPosXBeforeMoved,fPosZBeforeMoved),而(sPosX,sPosZ) 是您之后移动的点。在此图中,X 将是水平分量,而Z 将是垂直分量。想象一下,你面前举着一张照片。 X 是从左到右的轴,Z 是上下的轴,Y 是朝你出来并进入图片内部的轴。

我们可以通过取X坐标之间的差值来找到相邻(AC)段的长度,通过取Z之间的差值来找到对面(AB)段的长度坐标。我们只需要找到斜边的长度 (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)

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


祝你好运,玩得开心!

【讨论】:

  • 谢谢!我从来不知道我会这么快得到这么详细的答案,解释我所做的所有错误!你太棒了!
  • 哈哈谢谢 :) 仔细检查我的数学是否正确。如果是,并且您很高兴,请考虑接受我的回答,如果它对您有所帮助。点击我帖子顶部的复选标记图标,位于上下投票箭头下方的左侧。
  • 我不知道这是否是写这篇文章的正确地方,但既然你知道我在哪里挣扎:我使用的其他代码有什么问题? setVelZ(getPlayerEnt(), 速度 / Math.cos(getAngleMoving())); setVelX(getPlayerEnt(), speed / Math.sin(getAngleMoving()));
  • getanglemoving() 只是使用您对我的问题的解决方案来获取角度,只是我用 fpos's 替换了 fbeforemoveds 。 fpos 每秒检查 10 次,spos 每秒检查 10 次,但与 fpos 的时间不同。所以我有一个每秒更新 10 次的角度,并且更准确。我没觉得有什么不对。
  • 现在很好,您帮助了解了我需要了解的内容。我认为做 Math.Sin(o/h) 会给我 theta 的正弦,但多亏了你,我知道 theta 的罪是 o/h 并且反正弦会给我们任何语言选择返回的角度.这是因为我认为你的 x 和 z 轴混乱了,因为在我的世界中轴是混乱的,所以你计算错误的角度。我现在知道数学的价值,并且可能是我唯一要重点学习的课程。IT 现在不会测试我的知识,而是测试 Windows 电影制作器和 powerpoint 之类的垃圾软件。
猜你喜欢
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 2018-05-15
  • 2018-05-14
  • 2011-01-16
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多