## 三角函数
三角函数、勾股定理、两点间的距离,还有sin、cos、tan,是不是感觉这些很是熟悉,恍惚间回到了初中时代,想起了数学课本上那一道道让人头疼的三角函数。今天就让我们来回顾一下!
对于三角函数,我会分为两章来讲,这一章主要讲三角函数和反三角函数的基本公式:
- 角度与弧度的转换
- Math对象中的三角函数
- 实例:指红针
在下一章主要讲我们能利用三角函数做些什么:
波形(平滑的上下运动、线性运动、脉冲运动)
圆周运动与椭圆运动
两点间的距离(勾股定律)
现在我们就进入这一章的内容!
**1、三角函数**
**(1)角度和弧度**
角度和弧度都是角的度量单位,一弧度约等于57.2958°,反向计算可得360°(一个完整圆的角度)等于6.2832弧度(也就是2*PI),所以弧度(radians)和角度(degrees)的转换公式如下:
```
1弧度 = degrees * PI / 180;
1度 = radians * 180 / PI;
```
在JavaScript中是这样:
```
1弧度 = degrees * Math.PI / 180;
1度 = radians * 180 / Math.PI;
```
在后面,我们会经常用到这公式,如果记不住,可以写在纸上。
**(2)坐标系**
数学上的坐标系(下图左边)和网页坐标系(下图右边)是有所区别的:
![](https://box.kancloud.cn/b2529feab269f6665c6c622fd8cad53e_500x253.jpg)
从上图可以看到,网页坐标系相当于普通坐标系绕着x轴旋转180度得来的,两者y轴的正方向相反,而且网页是以左上角为坐标原点的,也就是o点,当然,就像上图一样,网页上也会有负方向。
也正是因为y轴正方向的不同,所以导致角度测量也是不同的,如下图:
![](https://box.kancloud.cn/b1ac86850718f5cfa547ba89240d2bdb_592x288.jpg)
实质就是绕着X轴旋转180度后得到canvas上的坐标,角度的正负很重要。
**(3)直角三角形**
![](https://box.kancloud.cn/be0de3b5e828d611061bbfb797f1c234_403x237.png)
相信大家对直角三角形并不会陌生(留意这张图:x是邻边,y是对边,R是斜边,θ是角度),在数学上,有如下三角函数:
```
正弦:sin(θ) = y / R
余弦:cos(θ) = x / R
正切:tan(θ) = y / x
/*反三角函数*/
反正弦:arcsin(y/R) = θ
反余弦:arccos(x/R) = θ
反正切:arctan(y/x) = θ
```
看得是不是有点晕晕的,如果你还想完整的了解三角函数,建议百度。
在JavaScript的Math对象中,已经给我们封装好了这些方法,我们只需如下调用:
```
Math.sin(θ*Math.PI/180)
Math.cos(θ*Math.PI/180)
Math.tan(θ*Math.PI/180)
/*反三角函数*/
Math.asin(y/R)*(180/Math.PI) = θ
Math.acos(x/R)*(180/Math.PI) = θ
Math.atan(y/x)*(180/Math.PI) = θ
```
我想你应该也注意到了,在使用Math对象中的三角函数时,并不是直接的传入 θ 角度值,而是使用 `θ*180/Math.PI `得到的值,这是因为Math对象中的三角函数采用的弧度制,也就是说,传入的值是弧度,而不是角度,反三角函数得到的值也是弧度,而不是角度。
注意:使用Math对象的三角函数时,一定要留意角度和弧度的转换。
在这里,还要额外的说一个常用(可能你会一直用它,而忽略Math.atan())的方法:
```
Math.atan2(y,x)
```
Math.atan2()也是一个反正切函数,不过它接受两个参数:对边和邻边的长度,一般是X坐标和Y坐标。
**Math.atan()和Math.atan2()的区别**:
Math.atan(θ)和Math.atan2(x,y)两个方法除了传入参数不一样外,它们的返回值也会有所不同:
Math.atan2()返回值的范围是-PI到PI之间(不包括-PI)的值,而Math.atan()返回的值范围是-PI/2到PI/2(不包括-PI/2和PI/2)之间。
我们再用一个例子来看一下区别:
下面使用 Math.atan() ,结果如下:
```
A: Math.atan(-1/2) -0.5 => Math.atan(-1/2)*180/Math.PI -26.57°
B: Math.atan(1/2) 0.5 => Math.atan(1/2)*180/Math.PI 26.57°
C: Math.atan(1/-2) -0.5 => Math.atan(1/-2)*180/Math.PI -26.57°
D: Math.atan(-1/-2) 0.5 => Math.atan(-1/-2)*180/Math.PI 26.57°
```
光是从上面得到的值,我们无法判断到底是三角形A还是C或B还是D。
而使用 Math.atan2() :
```![](https://box.kancloud.cn/4c7ddfe90ac1f10844b613c3cfd4c6d5_555x313.jpg)
A: Math.atan2(-1,2) -0.5 => Math.atan2(-1,2)*180/Math.PI -26.57
B: Math.atan2(1,2) 0.5 => Math.atan2(1,2)*180/Math.PI 26.57
C: Math.atan2(1,-2) 2.7 => Math.atan2(1,-2)*180/Math.PI 153.43
D: Math.atan2(-1,-2) -2.7 => Math.atan2(-1,-2)*180/Math.PI -153.43
```
显然,使用Math.atan2()得到的值都是不一样的,这样我们就可以很容易的知道第一个是A三角形,第二个是B三角形,第三个是C三角形,第四个是D三角形。
注意:这里不需记住具体值,只需记住正负号,还有大于90还是小于90。
同一个三角形得到不同的值是因为两个方法测量角的方式不一样(下面是两种方法对D三角形的测量):
![](https://box.kancloud.cn/709f09b0f0793e68bce3600247b7a47d_479x187.jpg)
注意:这个函数很有用。
光说不练这肯定不符合TG法则,所以下面我们来搞一个例子,相信大家都玩过指南针吧,当然,这里我们不会搞出一个指南针,而是搞出一个“指红针”。
canvas-demo/disk.html
对这里例子,还是直接上图:
![](https://box.kancloud.cn/a029fe58939411b9d99708051212c697_600x465.jpg)
在上面的图中,红色代表了三角磁铁的指向,先平移,A1是向右平移x1,向下平移y1后的A,B是鼠标点坐标,根据鼠标坐标和三角磁铁的中心点计算出需要旋转的角度,也就是上面的θ,然后旋转cavnas。
注意:每次绘制不同的三角磁铁时,必须先使用save()保存状态,再绘制完一个三角磁铁后,再用restore()恢复上一次的状态,不然的话,每次旋转平移都会在上一次的基础上平移旋转,而不是以(0,0)点平移,后旋转了。如果不明白,可以试试不用save()和restore(),看看会发生什么。
**总结**
常用的三角函数有:`Math.sin()、Math.cos()、Math.tan()`
常用的反三角函数有:`Math.asin()、Math.acos()、Math.atan()、Math.atan2()`(用的频率很高)
一般情况下,对canvas做变形(平移、旋转、缩放等)操作时,都要使用`save()`和`restore()`来保存和恢复状态。