反正切(Arctangent)
大家可能都猜到了,反正切簡(jiǎn)單地說(shuō)就是正切函數(shù)的反函數(shù)。我們只要輸入對(duì)邊與鄰邊的比值,就可以得到相應(yīng)的角度。 在 Flash 中有兩個(gè)函數(shù)可計(jì)算反正切。第一個(gè)就是像前面介紹過(guò)的函數(shù)一樣 Math.atan(ratio),只需提供對(duì)邊與鄰邊的比例值。例如,前面學(xué)過(guò)30度角的正切值約為0.577。試一下:
trace(Math.atan(0.577) * 180 / Math.PI);
輸出結(jié)果是一個(gè)近似30的數(shù),不是非常直觀易懂嗎,為什么還需要另一個(gè)函數(shù)呢?下面請(qǐng)看圖3-13,讓它來(lái)回答:
圖3-13 四個(gè)象限上的角
如圖3-13所示,有四個(gè)不同的角:A,B,C,D。角A和B,在X軸上為正數(shù),角C和D在X軸上為負(fù)數(shù),同樣,角A和D在Y軸上為負(fù)數(shù),而角B和C在Y軸上為正數(shù)。因此,四個(gè)內(nèi)角的比例分別為: A: –1/2 (–0.5) B: 1/2 (0.5) C: 1/ –2 (–0.5) D: –1/ –2 (0.5)
對(duì)邊與鄰邊之比為0.5,輸入Math.atan(0.5),并轉(zhuǎn)換為角度制,結(jié)果大約為 26.57,那么究竟所指的是角B還是角D呢??jī)蓚(gè)比例都為0.5那樣就無(wú)法分辨了,看似是個(gè)小問(wèn)題,但對(duì)于日后的工作確有很大的影響。
下面有請(qǐng) Math.atan2(y,x),這是 Flash 的另一個(gè)反正切函數(shù),它比 Math.atan(ratio)要有用得多。實(shí)事上,只需要學(xué)會(huì)這個(gè)函數(shù)的用法就可以了,函數(shù)中包括兩個(gè)參數(shù):對(duì)邊長(zhǎng)度與鄰邊長(zhǎng)度。有時(shí)常會(huì)誤寫成 x,y,請(qǐng)注意應(yīng)該是 y,x。請(qǐng)看如下示例,輸入 Math.atan2(1,2),然后記住這個(gè)結(jié)果: trace(Math.atan2(1, 2) * 180 / Math.PI); 輸出結(jié)果為 26.565051177078,這正是角B的度數(shù)。下面再輸入-1/-2(角D),再來(lái)試試:
trace(Math.atan2(-1, -2) * 180 / Math.PI);
出乎意料的結(jié)果–153.434948822922.為什么會(huì)這樣?圖3-14能給你解釋。
圖3-14 一個(gè)角的兩種表示方法
從角D自身的底邊開(kāi)始,它確實(shí)為26.57度,但別忘了 Flash 的角度是從 X 軸的正半軸順時(shí)針計(jì)算的。因此,從 Flash 的角度來(lái)衡量,則該角被視為-153.43度。下面就要開(kāi)始在 Flash 中實(shí)踐和應(yīng)用三角學(xué)了。
旋轉(zhuǎn)(Rotation)
我們想讓一個(gè)影片剪輯或 Sprite 影片通過(guò)旋轉(zhuǎn)來(lái)指向鼠標(biāo)的位置,這將是個(gè)挑戰(zhàn)。旋轉(zhuǎn)(rotation)將成為我們工具箱中非常的工具,可以應(yīng)用于游戲制作,鼠標(biāo)追蹤,界面設(shè)計(jì)等。
下面看一個(gè)示例。也可以根據(jù)以下步驟或打開(kāi)文檔類 RotateToMouse.as 和 Arrow.as(與本書中其它代碼一同在 www.friendsofed.com 下載),這些是已寫好的代碼。首先,需要讓物體旋轉(zhuǎn),它可以是一個(gè)在 Sprite 中繪制的箭頭(Arrow)。事實(shí)上,如果我們要反復(fù)應(yīng)用到這個(gè)箭頭,可以把它制作成一個(gè)類:
package { import flash.display.Sprite; public class Arrow extends Sprite { public function Arrow() { init(); } public function init():void { graphics.lineStyle(1,0,1); graphics.beginFill(0xffff00); graphics.moveTo(-50,-25); graphics.lineTo(0,-25); graphics.lineTo(0,-50); graphics.lineTo(50,0); graphics.lineTo(0,50); graphics.lineTo(0,25); graphics.lineTo(-50,25); graphics.lineTo(-50,-25); graphics.endFill(); } } }
這里使用到了繪圖 API (會(huì)在下一章介紹)來(lái)繪制箭頭。無(wú)論何時(shí)需要一個(gè)箭頭,只需寫一句 new Arrow()即可,在圖3-15中可看到顯示結(jié)果。當(dāng)繪制一些圖像并進(jìn)行旋轉(zhuǎn)時(shí),要注意它的指向,默讓地指向右邊,X的正半軸,這就是它旋轉(zhuǎn)到0度時(shí)的狀態(tài)。
我們先要?jiǎng)?chuàng)建一個(gè)Arrow類的實(shí)例,放致于舞臺(tái)中心,并讓它指向鼠標(biāo)的方向,如圖3-16。
圖3-15 使用繪圖API繪制的箭頭
圖3-16 下一次需要計(jì)算的值(圖丟失)
很熟悉嗎?與我們之前所講的三角形相同,只不過(guò)多加入了鼠標(biāo)與箭頭的坐標(biāo)。鼠標(biāo)的位置只需使用 mouseX 和 mouseY 屬性即可獲得,同樣,使用x,y屬性,獲得箭頭的位置。使它們的值相減,就得到了兩條邊的長(zhǎng)度,F(xiàn)在只需要使用 Math.atan2(dy,dx) 就可以求出夾角,然后把結(jié)果轉(zhuǎn)換為角度制,最后讓箭頭的 rotation 屬性等于這個(gè)夾角。代碼如下:
var dx:Number = mouseX - arrow.x; var dy:Number = mouseY - arrow.y; var radians:Number = Math.atan2(dy, dx); arrow.rotation = radians * 180 / Math.PI;
當(dāng)然,為了使之形成一個(gè)動(dòng)畫,還需要加入循環(huán)。如同前一章提到的,使用事件處理函數(shù)將會(huì)是最好的選擇,請(qǐng)使用 enterFrame 事件。以下是這個(gè)完整的文檔類:
package { import flash.display.Sprite; import flash.events.Event; public class RotateToMouse extends Sprite { private var arrow:Arrow; public function RotateToMouse() { init(); } private function init():void { arrow=new Arrow ; addChild(arrow); arrow.x=stage.stageWidth / 2; arrow.y=stage.stageHeight / 2; addEventListener(Event.ENTER_FRAME,onEnterFrame); } public function onEnterFrame(event:Event):void { var dx:Number=mouseX - arrow.x; var dy:Number=mouseY - arrow.y; var radians:Number=Math.atan2(dy,dx); arrow.rotation=radians * 180 / Math.PI; } } }
請(qǐng)確認(rèn) RotateToMouse.as 文件與 Arrow.as 文件在同一目錄下,以 RotateToMouse 作為文檔類,并為它創(chuàng)建 SWF。怎么樣?就像施了魔法一樣!假設(shè)如果我們沒(méi)有 Math.atan2 這個(gè)函數(shù),就要先通過(guò),dy除以dx求出對(duì)邊與鄰邊的比值,然后再寫入 Math.atan 函數(shù)。下面用 Math.atan 函數(shù)來(lái)代替 Math.atan2 函數(shù)來(lái)試一下,代碼如下:
var radians = Math.atan(dy / dx);
試試這種寫法,馬上就會(huì)發(fā)現(xiàn)問(wèn)題。如果鼠標(biāo)位于箭頭的左側(cè),箭頭不會(huì)指向鼠標(biāo),并與鼠標(biāo)相背離。能說(shuō)說(shuō)為什么嗎?回到有 A,B,C,D 四個(gè)角的圖(圖3-13),不要忘記角A和C擁有相同的比值,角B和D也是一樣。這樣一來(lái), Flash 就無(wú)法知道所指的是哪個(gè)角,所以只能得到A與或角B。如果,鼠標(biāo)處于D角區(qū)域,F(xiàn)lash 會(huì)回到B角區(qū)域并把箭頭指向這個(gè)角度。毫無(wú)疑問(wèn),這時(shí) Math.atan2 的好處就顯示出來(lái)了,書中會(huì)經(jīng)常用到這個(gè)函數(shù)。
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁(yè) 三角學(xué)應(yīng)用 [4] 下一頁(yè) 三角學(xué)應(yīng)用 [6]
◎進(jìn)入論壇RIA設(shè)計(jì)與應(yīng)用版塊參加討論
|