(1)角度和弧度
角度和弧度都是角的度量單位,一弧度約等于57.2958°,反向計(jì)算可得360°(一個(gè)完整圓的角度)等于6.2832弧度(也就是2*PI),所以弧度(radians)和角度(degrees)的轉(zhuǎn)換公式如下:
1弧度 = degrees * PI / 180;
1度 = radians * 180 / PI;
在JavaScript中是這樣:
1弧度 = degrees * Math.PI / 180;
1度 = radians * 180 / Math.PI;
在后面,我們會經(jīng)常用到這公式,如果記不住,可以寫在紙上。
(2)坐標(biāo)系
數(shù)學(xué)上的坐標(biāo)系(下圖左邊)和網(wǎng)頁坐標(biāo)系(下圖右邊)是有所區(qū)別的:
從上圖可以看到,網(wǎng)頁坐標(biāo)系相當(dāng)于普通坐標(biāo)系繞著x軸旋轉(zhuǎn)180度得來的,兩者y軸的正方向相反,而且網(wǎng)頁是以左上角為坐標(biāo)原點(diǎn)的,也就是o點(diǎn),當(dāng)然,就像上圖一樣,網(wǎng)頁上也會有負(fù)方向。
也正是因?yàn)閥軸正方向的不同,所以導(dǎo)致角度測量也是不同的,如下圖:
實(shí)質(zhì)就是繞著X軸旋轉(zhuǎn)180度后得到canvas上的坐標(biāo),角度的正負(fù)很重要。
(3)直角三角形
相信大家對直角三角形并不會陌生(留意這張圖:x是鄰邊,y是對邊,R是斜邊,θ是角度),在數(shù)學(xué)上,有如下三角函數(shù):
正弦:sin(θ) = y / R
余弦:cos(θ) = x / R
正切:tan(θ) = y / x
/*反三角函數(shù)*/
反正弦:arcsin(y/R) = θ
反余弦:arccos(x/R) = θ
反正切:arctan(y/x) = θ
看得是不是有點(diǎn)暈暈的,如果你還想完整的了解三角函數(shù),建議百度。
在JavaScript的Math對象中,已經(jīng)給我們封裝好了這些方法,我們只需如下調(diào)用:
Math.sin(θ*Math.PI/180)
Math.cos(θ*Math.PI/180)
Math.tan(θ*Math.PI/180)
/*反三角函數(shù)*/
Math.asin(y/R)*(180/Math.PI) = θ
Math.acos(x/R)*(180/Math.PI) = θ
Math.atan(y/x)*(180/Math.PI) = θ
我想你應(yīng)該也注意到了,在使用Math對象中的三角函數(shù)時(shí),并不是直接的傳入 θ 角度值,而是使用 θ*180/Math.PI 得到的值,這是因?yàn)镸ath對象中的三角函數(shù)采用的弧度制,也就是說,傳入的值是弧度,而不是角度,反三角函數(shù)得到的值也是弧度,而不是角度。
注意:使用Math對象的三角函數(shù)時(shí),一定要留意角度和弧度的轉(zhuǎn)換。
在這里,還要額外的說一個(gè)常用(可能你會一直用它,而忽略Math.atan())的方法:
Math.atan2()也是一個(gè)反正切函數(shù),不過它接受兩個(gè)參數(shù):對邊和鄰邊的長度,一般是X坐標(biāo)和Y坐標(biāo)。
Math.atan()和Math.atan2()的區(qū)別:
Math.atan(θ)和Math.atan2(x,y)兩個(gè)方法除了傳入?yún)?shù)不一樣外,它們的返回值也會有所不同:
Math.atan2()返回值的范圍是-PI到PI之間(不包括-PI)的值,而Math.atan()返回的值范圍是-PI/2到PI/2(不包括-PI/2和PI/2)之間。
我們再用一個(gè)例子來看一下區(qū)別:
下面使用 Math.atan() ,結(jié)果如下:
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()得到的值都是不一樣的,這樣我們就可以很容易的知道第一個(gè)是A三角形,第二個(gè)是B三角形,第三個(gè)是C三角形,第四個(gè)是D三角形。
注意:這里不需記住具體值,只需記住正負(fù)號,還有大于90還是小于90。
同一個(gè)三角形得到不同的值是因?yàn)閮蓚€(gè)方法測量角的方式不一樣(下面是兩種方法對D三角形的測量):
注意:這個(gè)函數(shù)很有用。
光說不練這肯定不符合TG法則,所以下面我們來搞一個(gè)例子,相信大家都玩過指南針吧,當(dāng)然,這里我們不會搞出一個(gè)指南針,而是搞出一個(gè)“指紅針”。
對這里例子,還是直接上圖:
在上面的圖中,紅色代表了三角磁鐵的指向,先平移,A1是向右平移x1,向下平移y1后的A,B是鼠標(biāo)點(diǎn)坐標(biāo),根據(jù)鼠標(biāo)坐標(biāo)和三角磁鐵的中心點(diǎn)計(jì)算出需要旋轉(zhuǎn)的角度,也就是上面的θ,然后旋轉(zhuǎn)cavnas。
注意:每次繪制不同的三角磁鐵時(shí),必須先使用save()保存狀態(tài),再繪制完一個(gè)三角磁鐵后,再用restore()恢復(fù)上一次的狀態(tài),不然的話,每次旋轉(zhuǎn)平移都會在上一次的基礎(chǔ)上平移旋轉(zhuǎn),而不是以(0,0)點(diǎn)平移,后旋轉(zhuǎn)了。如果不明白,可以試試不用save()和restore(),看看會發(fā)生什么。
總結(jié)
- 常用的三角函數(shù)有:Math.sin()、Math.cos()、Math.tan()
- 常用的反三角函數(shù)有:Math.asin()、Math.acos()、Math.atan()、Math.atan2()(用的頻率很高)
- 一般情況下,對canvas做變形(平移、旋轉(zhuǎn)、縮放等)操作時(shí),都要使用save()和restore()來保存和恢復(fù)狀態(tài)。
如有錯誤,歡迎指正!
下一章:《三角函數(shù)(2)》
更多建議: