canvas動畫包教不包會:三角函數(1)

2018-06-19 15:01 更新
(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)坐標系
數學上的坐標系(下圖左邊)和網頁坐標系(下圖右邊)是有所區(qū)別的:

從上圖可以看到,網頁坐標系相當于普通坐標系繞著x軸旋轉180度得來的,兩者y軸的正方向相反,而且網頁是以左上角為坐標原點的,也就是o點,當然,就像上圖一樣,網頁上也會有負方向。

也正是因為y軸正方向的不同,所以導致角度測量也是不同的,如下圖:



實質就是繞著X軸旋轉180度后得到canvas上的坐標,角度的正負很重要。


(3)直角三角形

相信大家對直角三角形并不會陌生(留意這張圖: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()的區(qū)別:
Math.atan(θ)和Math.atan2(x,y)兩個方法除了傳入參數不一樣外,它們的返回值也會有所不同:
Math.atan2()返回值的范圍是-PI到PI之間(不包括-PI)的值,而Math.atan()返回的值范圍是-PI/2到PI/2(不包括-PI/2和PI/2)之間。

我們再用一個例子來看一下區(qū)別:

下面使用 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() :

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三角形的測量):

注意:這個函數很有用。

光說不練這肯定不符合TG法則,所以下面我們來搞一個例子,相信大家都玩過指南針吧,當然,這里我們不會搞出一個指南針,而是搞出一個“指紅針”。


對這里例子,還是直接上圖:



在上面的圖中,紅色代表了三角磁鐵的指向,先平移,A1是向右平移x1,向下平移y1后的A,B是鼠標點坐標,根據鼠標坐標和三角磁鐵的中心點計算出需要旋轉的角度,也就是上面的θ,然后旋轉cavnas。


注意:每次繪制不同的三角磁鐵時,必須先使用save()保存狀態(tài),再繪制完一個三角磁鐵后,再用restore()恢復上一次的狀態(tài),不然的話,每次旋轉平移都會在上一次的基礎上平移旋轉,而不是以(0,0)點平移,后旋轉了。如果不明白,可以試試不用save()和restore(),看看會發(fā)生什么。


總結

  • 常用的三角函數有:Math.sin()、Math.cos()、Math.tan()
  • 常用的反三角函數有:Math.asin()、Math.acos()、Math.atan()、Math.atan2()(用的頻率很高)
  • 一般情況下,對canvas做變形(平移、旋轉、縮放等)操作時,都要使用save()和restore()來保存和恢復狀態(tài)。


如有錯誤,歡迎指正!


下一章:《三角函數(2)



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號