canvas動(dòng)畫(huà)包教不包會(huì):三角函數(shù)(2)

2018-06-19 14:59 更新
      這一章依舊是關(guān)于三角函數(shù)的,讓我們來(lái)看看使用三角函數(shù)能做些什么,內(nèi)容如下:
  1. 波形(平滑的上下運(yùn)動(dòng)、線性運(yùn)動(dòng)、脈沖運(yùn)動(dòng))
  2. 圓周運(yùn)動(dòng)與橢圓運(yùn)動(dòng)
  3. 兩點(diǎn)間的距離(勾股定律)

1、波形
看到下面這張邪惡的波形圖,我們又要感慨一聲:初中的回憶

沒(méi)錯(cuò),這就是正弦波,也就是正弦曲線(sin()),上面的圖只是正弦函數(shù)的一個(gè)周期[0,2π],對(duì)應(yīng)正弦值范圍是:[-1,1]。如果你要取sin()在[0,2π]之間的值,我們可以這樣獲?。?/div>

for(var angle = 0; angle < Math.PI*2; angle += 0.1){

  console.log(Math.sin(angle));

}

上面的值并沒(méi)有包括-1、1和0,因?yàn)橐?.1的步長(zhǎng)是不會(huì)出現(xiàn)π或π/2的整數(shù)倍。

再次提醒,Math對(duì)象中所有關(guān)于三角函數(shù)的計(jì)算都是基于 弧度 的。

還是那句話,不要紙上談兵,下面還是用例子說(shuō)話:

(1)平滑的上下運(yùn)動(dòng)


在上面的例子中,我們通過(guò) angle+=0.1 改變angle的值,然后傳遞給Math.sin(),它會(huì)根據(jù)angle值的變化,返回從0到1再變到-1最后回到0的值,最終就產(chǎn)生了跟正弦波軌跡一樣的平滑運(yùn)動(dòng),如下代碼:

ball.x += 1;   

ball.y += Math.sin(ball.angle) * 10;   

ball.angle += 0.1;


(2)線性運(yùn)動(dòng)
線性運(yùn)動(dòng)也可稱為勻速運(yùn)動(dòng),也就是物體朝著一個(gè)方向做勻速(等速度)運(yùn)動(dòng)。對(duì)于線性運(yùn)動(dòng),這里就不給例子了,你只需將上面平滑運(yùn)動(dòng)中的例子內(nèi)這段代碼注釋掉就是線性運(yùn)動(dòng):

ball.angle += 0.1;


(3)脈沖運(yùn)動(dòng)
我們都知道,動(dòng)畫(huà)并不僅僅局限于坐標(biāo)的變化,還有很多,比如:物體顏色、物體大小等等。而脈沖運(yùn)動(dòng)就是通過(guò)改變物體的大?。ū壤┒纬傻摹?/div>

在這個(gè)例子中,給Ball類添加了一個(gè)scale屬性,表示Ball的大小比例,通過(guò)下面的代碼改變比例:

ball.scale = 1 + Math.sin(ball.angle);   

ball.angle += 0.1;   

ball.radius = 10 * ball.scale;


特別強(qiáng)調(diào),不要讓上面的這些例子限制了你的思維,你可以利用正弦波進(jìn)行任何屬性的改變,相信你會(huì)得到各種有趣酷炫的視覺(jué)效果。

2、圓周運(yùn)動(dòng)與橢圓運(yùn)動(dòng)

(1)圓周運(yùn)動(dòng)
圓周運(yùn)動(dòng)是指繞著一個(gè)完整的圓形軌跡做運(yùn)動(dòng),也可以這樣理解,物體離圓心的距離不變的運(yùn)動(dòng)。

表達(dá)式:

sin(θ) = x1 / R   =>   x1 = R * sin(θ)

cos(θ) = y1 / R   =>   y1 = R * cos(θ)

實(shí)例:

主要計(jì)算公式(radius為50):

ball.x = centerX + Math.sin(ball.angle)*radius;   

ball.y = centerY + Math.cos(ball.angle)*radius;


(2)橢圓運(yùn)動(dòng)

我們將橢圓的長(zhǎng)軸和短軸分別設(shè)為2a和2b。



表達(dá)式:

x2 = a * cosθ

y2 = b * sinθ

橢圓和正圓的唯一區(qū)別就是,正圓上任何一個(gè)點(diǎn)到圓心的距離都是一樣的,而橢圓卻不一樣。


與正圓運(yùn)動(dòng)不一樣的是,橢圓運(yùn)動(dòng)是根據(jù)兩個(gè)半徑值來(lái)計(jì)算的(radiusX為100,radiusY為50):

ball.x = centerX + Math.sin(ball.angle)*radiusX;   

ball.y = centerY + Math.cos(ball.angle)*radiusY;


3、兩點(diǎn)間的距離(勾股定律)

很多時(shí)候,我們需要知道兩個(gè)物體間的距離(對(duì)于后面的碰撞檢測(cè)很重要),這時(shí)我們又要用到數(shù)學(xué)了,那就是勾股定律(要知道詳情,請(qǐng)百度)。


假設(shè)有點(diǎn)A(x1,y1)和點(diǎn)B(x2,y2),要求它們的距離很簡(jiǎn)單:

var dx = x2 - x1;

var dy = y2 - y1;

var dist = Math.sqrt(dx * dx + dy * dy);

dist就是兩點(diǎn)間的距離了。其實(shí)在上面我們用到了很多,比如圓的半徑,就是這樣計(jì)算來(lái)的,只不過(guò)它有一個(gè)特殊點(diǎn)(原點(diǎn)(0,0)),就相等于 x1 = 0, y1 = 0 。


總結(jié)

到這里,關(guān)于三角函數(shù)的內(nèi)容已經(jīng)講完了,雖然不能包含全部,但是利用這些,你能弄出很多效果(前提是你去思考)。


這兩章需要各位慢慢去看,爭(zhēng)取多動(dòng)手吧!


如有錯(cuò)誤,歡迎指正!


附錄:

(1)角度與弧度互轉(zhuǎn)

radians = degrees * Math.PI /180

degrees = radians * 180 / Math.PI


(2)旋轉(zhuǎn)(弧度)

dx = point.x - object.x;

dy = point.y - object.y;

boject.rotation = Math.atan2(dy, dx);


(3)平滑運(yùn)動(dòng)

value = center + Math.sin(angle) * range;

angle += speed;


(4)圓形運(yùn)動(dòng)

xposition = centerX + Math.cos(angle) * radius;

yposition = centerY + Math.sin(angle) * radius;

angle += speed;


(5)橢圓運(yùn)動(dòng)

xposition = centerX + Math.cos(angle) * radiusX;

yposition = centerY + Math.sin(angle) * radiusY;

angle += speed;


(6)兩點(diǎn)間的距離

var dx = x2 - x1;

var dy = y2 - y1;

var dist = Math.sqrt(dx * dx + dy * dy);




以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)