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

资料来源:维基百科
通过查看A
这个直角三角形的点,我们看到线段AC
和之间形成了一个角度AB
。这个角度和之间的关系sin
是sin
对边的长度与斜边的比值。换句话说:
sin A = opposite / hypotenuse = a / h
这意味着如果我们取a / h
,这等于sin
位于 的角度A
。因此,要找到实际角度,我们需要在这个等式的两边应用反正弦算子。像这样:
A = asin(a / h)
例如,如果a = 1
和h = 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 / 2
或x >= -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
,但让我们来看看cos
。 cos
是相邻边的长度与斜边的比值。换句话说:
cos A = adjacent / hypotenuse = b / h
这解释了这部分:
(sPosX - fPosXBeforeMoved) / Math.sqrt(Math.pow(sPosX - fPosXBeforeMoved, 2) +
Math.pow(sPosZ - fPosZBeforeMoved, 2));
请注意,我将减法和sPosX
与fPosXBeforeMoved
您之前代码中的内容进行了比较。原因是当你检查前点和后点时,总是先出现后点,然后再检查前点。在底部计算斜边时,这无关紧要,因为无论从哪个顺序减去值,我们都会取减法的平方,因此无论顺序如何,您都会得到相同的数字。为了保持一致,我决定在这里交换斜边的顺序。订单确实最重要的是,当你减去时,值是正数还是负数会在你最终找到角度时产生影响。
请注意,这个除法总是在 -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)
至于你现在拥有的东西,我怀疑你只是在测量相邻和斜边的比率,如果你想检测你在每个轴上的交叉位置,这完全没问题。如果你想找到实际的角度,我会使用上面的代码。
祝好运并玩得开心点!