好的,让我们快速回顾一下sin 和asin 是什么。看看下图中的这个直角三角形:
来源:Wikipedia
通过查看这个直角三角形的点A,我们看到线段AC 和AB 之间形成了一个角度。这个角度和sin的关系是sin是对边的长度与斜边的比值。换句话说:
sin A = opposite / hypotenuse = a / h
这意味着如果我们取a / h,这等于位于A 的角度的sin。因此,要找到 实际 角,我们需要在该等式两边应用 inverse 正弦算子。因此:
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 位置。
我们实际上可以用这样的直角三角形来表示它(请原谅糟糕的图表):
我们可以在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,但让我们看看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)
至于你现在所拥有的,我怀疑你只是在测量相邻和斜边的比率,如果你想检测你在每个轴上的交叉位置,这完全没问题。如果你想找到实际的角度,我会使用上面的代码。
祝你好运,玩得开心!