《每週一點canvas動畫》——三角函數

本節主要內容有:javascript

  • 三角函數介紹html

  • 經常使用三角函數解析java

  • 鼠標跟隨角度旋轉canvas

看到三角函數,勾股定理這樣的數學名詞是否是有種雙腿打顫的感受啊!好吧,就算你已經嚇尿了,也不可否認咱們中學學習的知識終於有了用武之地,挽起袖子,開整!!!bash

一、三角函數

什麼是三角函數呢?簡單的定義:所謂三角函數,在幾何上來講就是夾角與邊的關係!爲了更直觀的表示,也爲了讓忘記的同窗回憶起來,這裏我給個示意圖。函數

圖片描述

在上圖中例出了幾個經常使用的三角函數,角度與邊(x, y和R)之間的關係如公式所示!那麼在canvas中角度與邊之間的關係是怎樣的呢?首先,咱們須要知道的是canvas中座標是如何定義的。工具

圖片描述

如圖所示,與普通座標不一樣,canvas座標以整個畫布的左上角做爲座標原點,y軸朝下爲正,x軸水平向右。座標不一樣,對應的角度表示就有所差別,這個差別主要體如今角度的正負上。學習

圖片描述

上圖中canvas的座標與普通座標感受同樣,但我想表達的是在canvas中順時針方向爲正,逆時針爲負。動畫

二、經常使用三角函數

前面咱們簡單的介紹了三角函數的表示方法以及canvas的座標系統。可是,在實際開發中咱們不只想要經過角度來推出兩邊的距離長度比值。而更關心的是如何經過已知的距離(由於座標的位置很好肯定)來推出角度。這裏咱們要用到反三角函數this

sin(θ)=x/R   --->  θ = arcsin(x/R)
cos(θ)=y/R   --->  θ = arccos(y/R)
tan(θ)=x/y   --->  θ = arctan(x/y)

對應到javascript中,相應表示方法以下。

sin(θ)  --->  Math.sin( θ * Math.PI/180 )
cos(θ)  --->  Math.cos( θ * Math.PI/180 )
tan(θ)  --->  Math.tan( θ * Math.PI/180 )

θ = arcsin(x/R) ---> Math.asin(x/R)*(180/Math.PI)
θ = arccos(y/R) ---> Math.acos(y/R)*(180/Math.PI)
θ = arctan(x/y) ---> Math.atan(x/y)*(180/Math.PI)

好吧!看到這裏也許你已經噁心得想吐了。可是,沒辦法這就是數學的魅力!這裏須要強調的是:canvas中角度的表示採用的是弧度制。這樣你就能夠理解 θ * Math.PI/180是將角度轉成弧度,好比:30° = 30 * π /180 = π / 6。 而將弧度轉成角度天然就要用弧度值`Math.asin(x/R) 乘上180/Math.PI`。這之間的轉換關係,慢慢想一想就明白了!

三、Math.atan2(dy, dx)

相比於Math.asin()和Math.cos()這兩個函數,Math.atan()在開發中用到的更多。它能夠直接經過兩個直角邊獲得對應的角度值。相比於其餘兩個須要經過計算長邊來獲得角度值來講,計算過程更加簡單!可是,該函數在角度的斷定上回出現一個問題——存在兩個相同的角度值而沒法斷定物體具體的旋轉角度。詳細說明以下圖所示。

圖片描述

由於,tan函數的週期是(-π/2, π/2),因爲這一特性致使電腦是沒法判斷旋轉的究竟是哪一個角度!!!這時,另外一個函數就橫空出世了,噹噹噹當,他就是Math.atan2(dy, dx)!他不只解決了上面咱們說的問題,並且只須要傳入橫縱座標距離就能夠計算出對應的角度值!是否是很酷。

四、跟隨鼠標旋轉

本章的理論知識已經介紹完成。如今,開始咱們的第一個demo——rotate-to-mouse.html顧名思義就是跟隨鼠標旋轉。首先建立一個文件arrow.js,這個文件是使用canvas畫一個箭頭,而且爲了從此方便使用,將它寫成一個類文件!代碼以下:

arrow.js文件

    function Arrow() {
        this.x = 0;  //初始位置
        this.y = 0;
        this.rotation = 0;  //初始旋轉角度
        this.color = '#ffff00';

    }
    //在原型上定義draw方法
    Arrow.prototype.draw = function(context){
        context.save();
        context.translate(this.x , this.y); //將座標移到this.x 和 this.y
        context.rotate(this.rotation); //設置旋轉角度
        context.lineWidth = 5;  //設置線寬
        context.fillStyle = this.color; //設置填充色
        context.beginPath();  //路徑開始
        context.moveTo(-50,-25);
        context.lineTo(0,-25);
        context.lineTo(0,-50);
        context.lineTo(50,0);
        context.lineTo(0,50);
        context.lineTo(0,25);
        context.lineTo(-50,25);
        context.closePath(); //路徑閉合
        context.stroke(); //描邊
        context.fill(); //填充
        context.restore();
    }

如今咱們在rotate-to-mouse.html文件中引入它,來建立一個箭頭

rotate-to-mouse.html 文件

  <canvas id='canvas' width="500" height="500" style="background:#ccc;">
      you browser not support canvas
  </canvas>

  <script src="../js/utils.js"></script> //引入咱們的工具函數文件
  <script src="../js/arrow.js"></script> //引入咱們的箭頭函數文件
  <script>
      window.onload = function(){
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        var centerX = canvas.width/2;
        var centerY = canvas.height/2;
        
        //傳入canvas,獲取鼠標在canvas上移動是的座標
        var mouse = utils.captureMouse(canvas);
             
        //新建一個arrow對象
        var arrow = new Arrow();
             
        //將arrow的座標設置爲canvas的中心
        arrow.x = centerX;
        arrow.y = centerY;
                 
      //動畫循環函數
      (function drawFrame(){
          window.requestAnimationFrame(drawFrame,canvas);
          context.clearRect(0, 0, canvas.width, canvas.height);
                  
          //獲取dy,dx值
          var dx = mouse.x - arrow.x,
          dy = mouse.y - arrow.y;
                      
          //設置旋轉角度
            arrow.rotation = Math.atan2(dy, dx);
                    
         //調用draw方法畫出
           arrow.draw(context);

      })();
}

</script>

咱們最終獲得的結果就是一個,能夠跟隨鼠標旋轉的箭頭。

圖片描述

總結

這節你應該學會了如何運用三角函數,控制物體的旋轉。重點公式:

dx = mouse.x - object.x;
dy = mouse.y - object.y;
object.rotation = Math.atan2(dy,dx);
相關文章
相關標籤/搜索