1. 基本概念
Math.atan2()方法计算二维坐标系中任意一个点(x, y)和原点(0, 0)的连线与X轴正半轴的夹角大小。为了更好地理解,我们用一个更形象的过程来描述Math.atan2()方法的原理:我们将X轴正半轴绕着原点旋转,直到它经过目标点(x, y);在这个旋转过程中,X轴正半轴扫过的角就是Math.atan2()方法要求的那一个角。
我们知道一个角的大小可以用角度值表示也可以用弧度值表示,那么Math.atan2()方法的返回值是哪一种呢?答案就是,Math.atan2()方法返回的是所求角的弧度值,并且在区间[-π, π]之间。
调用Math.atan2()方法的语法形式如下所示:
Math.atan2(y, x);
该方法的参数就是目标点的坐标,但要特别注意的是,纵坐标y是第一个参数而横坐标x是第二个参数;这和我们平时的习惯相反,千万不要搞错了。参数x和y都应该是数字,即它们都属于Number类型;如果某个参数不是Number类型的,那么它会先被自动转换为Number类型。
2. 旋转方向
上面我们已大致说明了Math.atan2()方法的作用,但还有一些细节没有解释清楚。比如,X轴正半轴沿着顺时针和逆时针方向都能旋转到目标点上,那么以哪个方向的旋转角度为准呢?JavaScript的数字类型包含NaN、+0、-0、正无穷(+Infinity)和负无穷(-Infinity)这5个特殊数字,那么当传递的参数是某个特殊数字时,又要哪些注意点呢?
X轴正半轴的旋转方向主要由目标点(x, y)的纵坐标y的正负号决定,当y是正数(包括+0)时,沿逆时针方向旋转,此时扫过的角是正的。当y是负数(包括-0)时,沿顺时针方向旋转,此时扫过的角是负的。
比如点(-2, +0),首先它的y坐标(+0)为正,所以X轴正半轴要向逆时针方向旋转并且扫过的角是正的。X轴正半轴必须旋转180度(弧度值为π)和X轴负半轴重合才能经过点(-2, +0),所以Math.atan2(+0, -2)等于π。这里再次提醒一下,目标点的y坐标是Math.atan2()方法的第一个参数,而x坐标是第二个参数。
作为对比,我们再来分析点(-2, -0)。首先它的y坐标(-0)为负,因此X轴正半轴要向顺时针方向旋转并且扫过的角是负的。同样地,X轴正半轴必须旋转180度和X轴负半轴重合才能经过点(-2, -0),所以Math.atan2(-0, -2)等于-π。
虽然在数学意义上(-2, +0)和(-2, -0)两个点是完全相同的,但在JavaScript中某些时候它们却并不完全一致。
3. 参数为特殊数字
首先,当参数x和y中任意一个为NaN时,那么Math.atan2()方法的结果就也为NaN。这很好理解,因为此时Math.atan2()方法不能执行任何有意义的运算。
我们主要需要关注的是目标点为原点,且横坐标分别为+0和-0时的情况。此时,当目标点的横坐标为-0时,JavaScript认为该点在X轴负半轴上,而不在正半轴上。相反,当目标点的横坐标为+0时,JavaScript认为该点在X轴正半轴上,而不在负半轴上。
比如点(-0, 0),首先它的y坐标为正,所以X轴正半轴应该向逆时针方向旋转并且扫过的角是正的。因为点(-0, 0)在X轴负半轴上,所以X轴正半轴需要旋转180度和X轴负半轴重合时才能经过点(-0, 0),因此Math.atan2(0, -0)等于π。
再来看点(+0, 0),首先它的y坐标为正,所以X轴正半轴应该向逆时针方向旋转并且扫过的角是正的。因为点(+0, 0)本身就在X轴正半轴上,所以X轴正半轴不需要旋转(或者说旋转0度),因此Math.atan2(0, +0)等于+0。
对于Y轴上除原点外的其它点(这些点的y坐标大于或小于0),它们的横坐标为+0或-0对最终确定夹角没有影响。
当参数包含无穷的时候更好理解,此时想象目标点在某个方向或两个方向上的无穷远处。比如点(2, +Infinity),当y坐标趋近于正无穷时,该点和原点的连线也趋近于和Y轴正半轴重合,因此Math.atan2(+Infinity, 2)等于π/2。
4. 示例
在前面我们分析了很多目标点和X轴正半轴的夹角大小,现在我们就以这些点的坐标为参数来实际调用Math.atan2()方法,看看它们的结果是否和我们分析的一样。最后再提醒一下,目标点(x, y)的y坐标是Math.atan2()方法的第一个参数,而x坐标是第二个参数。
以上代码的执行结果如图1所示:
图1 示例代码的执行结果
(完)
热门跟贴