三角学
三角学在动画技术中被广泛使用,不管是2D动画亦或是3D动画,都离不开三角学。
说到三角学,相信不少人会下意识地回避数学与三角学,毕竟说起数学的种种逻辑与公式,脑袋就大了。事实上,我们不必过于担心自己的数学不够好而影响到动画编程,大多数情况下,你可能只需处理好与位置、距离以及角相关的变量就行。
其实学习三角学最主要的是掌握各种边与角的关系 ,而且实现基本动画的90%的三角学知识都可归结于两个常用的三角函数:Math.sin 与 Math.cos。
1、角度与弧度
角的度量单位分别有角度和弧度两大系统,对于角度系统,相信我们都不陌生。不过在衡量角的大小的时候,计算机却更倾向于使用弧度的概念。所以无论喜欢与否,你都需要了解弧度。
角度与弧度的转换公式
▲▲▲
2、canvas坐标系
常见的二维坐标系,其坐标原点(0,0)通常位于空间的正中心,x轴的坐标值向右以正数的形式不断增大,向左以负数的形式 不断减小,而y轴的坐标值向上以正数的形式不断增大,向下以负数的形式不断减小。
而canvas元素是基于视频画面的坐标系,其坐标原点(0,0)处在canvas画布的左上角,x轴的坐标值从左往右不断增大,y轴的坐标值是从上往下不断增大。
除了坐标系之外,在大多数系统中,角度的测量是以逆时针方向为正值的,0°表示一条线沿x轴正方向延伸。但在canvas元素中,顺时针的角度才是正值,逆时针的角度反而成了负值。
3、三角函数
三角函数是基本初等函数之一,是以角度为自变量,角度对应任意角终边与单位圆交点坐标或其比值为因变量的函数。
常见的三角函数包括正弦函数、余弦函数和正切函数。一般用于计算三角形中未知长度的边和未知的角度。
(1)正弦
一个角的正弦表示与该角相对的直角边与斜边的比例。
在JavaScript中,使用Math.sin(angle) 函数计算正弦值。
如上图显示的是一个30°角的三角形,该30°角的对边长度为1,斜边长度为2,它们的比率是1 : 2,即1/2 或 0.5。因此,我们可以认为30°角的正弦值为0.5。
用 JavaScript 函数计算30°角正弦值如下:
注意:在开始计算正弦值之前,第一步我们需要将角度值转换为弧度值,然后再进行计算。
执行结果如下:
执行代码后我们发现得到的是一串很长的浮点数,这是因为二进制电脑在表示浮点数时经常会出现的结果。我们可以四舍五入处理把它当作0.5即可。
但是在canvas坐标系中,垂直向上以及逆时针的角度均是负值,所以在上图三角形中,角的对边和角自身都是负值。
如此一来,对边和斜边的比例就变成了-1/2,即-0.5:
正弦值所对应的角度变成了-30°。
-30°角的正弦值则为-0.5。
(2)余弦
一个角的正弦表示与该角相对的邻边与斜边的比例。
在JavaScript中,使用Math.cos(angle) 函数计算正弦值。
如上图显示的是一个30°角的三角形,该30°角的邻边相对于 角向右方向延伸,所以在x轴上长度是正值,长度为1.73,斜边长度为2,它们的比率是1.73 : 2,即0.866。因此,我们可以认为-30°角的余弦值为0.866。
用 JavaScript 函数计算该30°角余弦值如下:
执行结果如下:
(3)正切
正切是另一个重要的三角函数,在 JavaScript 中通过函数
Math.tan(angle) 表示,它表现的是对边与邻边的关系。
用 JavaScript 函数计算该30°角正切值如下:
执行结果如下:
实际上,在日常的动画代码中很少用到正切,用得比较频繁的主要是正弦和余弦。
(4)反正切
为什么不说反正弦和反余弦呢?其实反正弦和反余弦同正切一样,在一般的动画场景中不太用到,而在动画开发中,反正切起的作用反而更大些。
反正切是正切的逆运算,输入角的对边和邻边的比率,通过计算反正切就可得到角的弧度。在 JavaScript 中通过函数Math.atan(ratio) 表示。
由上第3点正切可以看出,30°角的正切值是0.577(四舍五入),由此可根据正切值计算出对应角度如下:
注意:计算得到的是弧度值,需要把弧度转换为角度。
执行结果如下:
一个接近30的值,即表示角度为30°
我们细心观察就会发现这里存在这样一个问题:
如图所示的4个三角形A、B、C、D,分别用正切函数
Math.atan(ratio)计算它们的正切值如下:
- A:-1 / 2,即 -0.5,
- Math.atan(-0.5) = -26.57°
- B:1 / 2, 即 0.5,
- Math.atan(0.5) = 26.57°
- C:1 /(-2),即 -0.5,
- Math.atan(-0.5) = -26.57°
- D:(-1)/(-2),即 0.5,
- Math.atan(0.5) = 26.57°
(以上计算省略了弧度转角度,默认计算出了角度)
我们可以看到,仅凭 Math.atan(-0.5) = -26.57°,是无法分辨这个三角形是A还是C,同理,B与D亦是无法分辨。
那么是否就无法解决这个问题?非也!
在 JavaScript 中,还有另一个反正切函数:
Math.atan2(y, x)
该函数接受两个参数:对边与邻边的长度,从而计算出弧度的值,它的不同之处在于,得出的角度值是从x轴正轴开始以逆时针方向计算的。
这时我们用 Math.atan2(y, x) 计算A、B、C、D 这4个三角形的角度:
- A:Math.atan2(-1, 2) = -26.57°
- B:Math.atan2(1, 2) = 26.57°
- C:Math.atan2(1, -2) = 153.43°
- D:Math.atan2(-1, -2) = -153.43°
由此我们可知,在canvas坐标系统中,我们所关注的三角形D的角度为 -153.43° 而不是 26.57°,由此我们就可以很方便的分辨出三角形A和C,B和D具体是哪一个了!
本章小结
角度与弧度互换
三角函数
正弦
余弦
正切
反正切