橢圓運動
想要獲得一個橢圓該怎么辦呢,其實很簡單,問題就在于半徑。如果讓x和y運動的大小相同,那么就得到一個圓。如果想得到一個橢圓形,我們只需要在計算x和y位置時使用不同的半徑值: radiusX 和 radiusY 。從嚴格的幾何觀點來看,使用這兩個名稱實在不怎么好,但是它們確實非常簡單易懂,也非常好記非常直觀,所以我還是堅持使用這兩個變量名。下面看看它們是如何配合的,見 Oval.as:
package { import flash.display.Sprite; import flash.events.Event; public class Oval extends Sprite { private var ball:Ball; private var angle:Number = 0; private var centerX:Number = 200; private var centerY:Number = 200; private var radiusX:Number = 200; private var radiusY:Number = 100; private var speed:Number = .1; public function Oval() { init(); } private function init():void { ball = new Ball(); addChild(ball); ball.x = 0; addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(event:Event):void { ball.x = centerX + Math.cos(angle) * radiusX; ball.y = centerY + Math.sin(angle) * radiusY; angle += speed; } } }
這里, radiusX 為200,意味著小球在距離 centerX 200個像素內(nèi)左右運動。 radiusY 為100,意味著小球上下運動的范圍只有100像素,這樣就得到了一個不勻稱的圓。
勾股定理
最后,介紹一下勾股定理。雖然并不能算是三角學中正式的一部分,但是它與我們這個學科還是有一些關系的,并且還涉及到一個將來會經(jīng)常使用的公式,所以在這里介紹它非常合適。
勾股定理是很久以前一個希臘人發(fā)明。這個定理是說 A的平方 + B的平方 = C的平方 ,聽起來好像是兒歌,如果大家之前學過這個定理,那么交流起來效果最好。
深入探討一下,另一種對該定理的敘述是:直角三角形的兩條直角邊的平方和等于斜邊的平方,這句話真正說到點子上了。請看圖3-21所示直角三角形。 兩條直角邊A和B長度為3和4,斜邊C長度為5。畢達哥拉斯(Pythagoras)先生告訴我們 A2 + B2 = C2 。加入一些數(shù)字來檢驗一下,32 + 42 = 52,計算出 9 + 16 = 25。是的,非常正確。
圖3-21 一個直角三角形
如果大家已經(jīng)知道了這個口決,那么勾股定理只不過就是一種有趣的關系。如果中知道其中兩條邊的長度,那么勾股定理就派上用場了,可以用它很快地求出第三條邊的長度。在 Flash 中,最常見的情況是我們只知道兩條直角邊的長度要求出斜邊的長度。比如,求出兩點間的距離。
兩點間距離
假設在舞臺上有兩個 Sprite 影片,想要求出它們之間的距離。這是勾股定理在 Flash 中最為常見的應用。那么如何實現(xiàn)呢?已知兩個 Sprite 的 x,y 坐標,把第一個影片的位置稱為x1,y1,另一個影片的位置稱為 x2,y2,見圖3-22。
圖3-22 兩個物體間的距離是多少?
如果你在本章中看了太多的直角三角形,那么很容易就把圖3-22看成一個直角三角形,而那條距離線(distance)就是三角形的斜邊。在圖3-23中,加入了這個三角形并填入了數(shù)字。
圖3-23 變成一個直角三角形
dx為兩個影片之間的x軸,dy為它們之間的y軸。用x2減x1就得到了dx的值:58 – 50 = 8,同樣,用y2-y1等于6得到dy的值。現(xiàn)在使用勾股定理,將dx,dy的平方相加,就得到了距離(distance)的平方。
換言之,62 + 82 = dist2,相當于 36 + 64(=100) = dist2。基礎代數(shù)學講過可以通過開平方把它轉(zhuǎn)化為 = dist。這樣一來,就可以得出兩個影片之間的距離為 10。
現(xiàn)在,把它抽像成一個公式,這樣的話,今后再遇到同樣的問題,就可以直接使用這個公式了。有兩個位置 x1,y1 和 x2,y2,先計算出 x 的距離和 y 的距離,然后求出它們的平方和,最后求出平方根,下面請看 ActionScript 寫法:
dx = x2 – x1; dy = y2 – y1; dist = Math.sqrt(dx*dx + dy*dy);
請?zhí)貏e注意這些代碼,它們將是我們工具箱中又一個最好的工具。前兩句是獲得x,y軸上的距離。最后一句分為三個步驟:計算每個值的平方,把它們相加,求出平方根。下面進行一下實踐,文檔類 Distance.as ,創(chuàng)建了兩個 Sprite 影片,并隨機擺放,最后計算出它們之間的距離。
package { import flash.display.Sprite; public class Distance extends Sprite { public function Distance() { init(); } private function init():void { var sprite1:Sprite = new Sprite(); addChild(sprite1); sprite1.graphics.beginFill(0x000000); sprite1.graphics.drawRect(-2, -2, 4, 4); sprite1.graphics.endFill(); sprite1.x = Math.random() * stage.stageWidth; sprite1.y = Math.random() * stage.stageHeight; var sprite2:Sprite = new Sprite(); addChild(sprite2); sprite2.graphics.beginFill(0xff0000); sprite2.graphics.drawRect(-2, -2, 4, 4); sprite2.graphics.endFill(); sprite2.x = Math.random() * stage.stageWidth; sprite2.y = Math.random() * stage.stageHeight; var dx:Number = sprite1.x - sprite2.x; var dy:Number = sprite1.y - sprite2.y; var dist:Number = Math.sqrt(dx * dx + dy * dy); trace(dist); } } }
編譯執(zhí)行這個動畫后,就得到了兩個影片之間的距離。每次執(zhí)行,兩個影片的位置都會不同。不論它們處于什么位置,我們所獲得的距離都是正數(shù)。有趣吧,但是還不
夠動態(tài),在下面這個示例,可以實時地獲得影片的距離,請試一下這個文檔類
MouseDistance.as: package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.text.TextField; public class MouseDistance extends Sprite { private var sprite1:Sprite; private var textField:TextField; public function MouseDistance() { init(); } private function init():void { sprite1 = new Sprite(); addChild(sprite1); sprite1.graphics.beginFill(0x000000); sprite1.graphics.drawRect(-2, -2, 4, 4); sprite1.graphics.endFill(); sprite1.x = stage.stageWidth / 2; sprite1.y = stage.stageHeight / 2; textField = new TextField(); addChild(textField); stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); } public function onMouseMove(event:MouseEvent):void { graphics.clear(); graphics.lineStyle(1, 0, 1); graphics.moveTo(sprite1.x, sprite1.y); graphics.lineTo(mouseX, mouseY); var dx:Number = sprite1.x - mouseX; var dy:Number = sprite1.y - mouseY; var dist:Number = Math.sqrt(dx * dx + dy * dy); textField.text = dist.toString(); } } }
在這里dx和dx的值是用 sprite1 的位置減去當前鼠標位置得出的,dist的值放入一個文本框中進行顯示,并在影片和鼠標之間繪制一條線(在下一章繪圖API中會學到)。最后,將所有這些代碼放到處理函數(shù) onMouseMove 中,每次鼠標移動時進行刷新。測試一下這個文件,并移動鼠標,鼠標與影片剪輯之間會連接上一條線,并實時讀取線的長度。
后面的章節(jié)中,在學到碰撞檢測時,我們會發(fā)現(xiàn)內(nèi)置的碰撞檢測(hit testing)方法存在著先天不足,然后會看到使用勾股定理公式完成基于距離(distance-based)碰撞檢測方法。它還非常適合用于計算重力或彈力等,因為這些力的大小與兩個物體之間的距離成正比。
本章重要公式
現(xiàn)在我們已經(jīng)有了一個全新的工具箱,同時又多了不少工具,全部所有的工具將會在第19章列出,那么讓我們看看現(xiàn)在都有了哪些工具。注意,這些公式非常地抽象和簡化,里面不包括數(shù)據(jù)類型和變量定義,在類中使用這些公式時,是否使用這些給出的句型取決于你。
基本三角函數(shù)的計算: 角的正弦值 = 對邊 / 斜邊 角的余弦值 = 鄰邊 / 斜邊 角的正切值 = 對邊 / 鄰邊
角度制與弧度制的相互轉(zhuǎn)換: 弧度 = 角度 * Math.PI / 180 角度 = 弧度 * 180 / Math.PI
向鼠標旋轉(zhuǎn)(或向某點旋轉(zhuǎn)):
// substitute mouseX, mouseY with the x, y point to rotate to dx = mouseX - sprite.x; dy = mouseY - sprite.y; sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI;
創(chuàng)建波形:
// assign value to x, y or other property of sprite or movie clip, // use as drawing coordinates, etc. public function onEnterFrame(event:Event){ value = center + Math.sin(angle) * range; angle += speed; }
創(chuàng)建圓形:
// assign position to x and y of sprite or movie clip, // use as drawing coordinates, etc. public function onEnterFrame(event:Event){ xposition = centerX + Math.cos(angle) * radius; yposition = centerY + Math.sin(angle) * radius; angle += speed; }
創(chuàng)建橢圓:
// assign position to x and y of sprite or movie clip, // use as drawing coordinates, etc. public function onEnterFrame(event:Event){ xposition = centerX + Math.cos(angle) * radiusX; yposition = centerY + Math.sin(angle) * radiusY; angle += speed; }
計算兩點間距離:
// points are x1, y1 and x2, y2 // can be sprite / movie clip positions, mouse coordinates, etc. dx = x2 – x1; dy = y2 – y1; dist = Math.sqrt(dx*dx + dy*dy);
本文鏈接:http://m.95time.cn/tech/multimedia/2008/5751.asp
出處:藍色理想
責任編輯:bluehearts
上一頁 三角學應用 [8] 下一頁
◎進入論壇RIA設計與應用版塊參加討論
|