《每週一點canvas動畫》——圓周運動

接《每週一點canvas動畫》——波形運動

圓周運動能夠分爲兩種基本的形式:正圓運動橢圓運動
在講解圓周運動以前,必不可少的數學公式即將襲來。so,各位騷年們,請護好本身的膝蓋。聽不懂不要緊,只要明白其中的原理就行。固然,能懂是最好的,這對後面學習高級動畫是頗有幫助的。好吧,廢話少說直接上菜。canvas

1.正圓運動

通常狀況下,圓的直角座標方程能夠表示爲:x2+y2=R2,根據此公式能夠得出圓在直角座標中的軌跡。也許,你會說這樣就能夠經過改變x,y的座標位置讓物體作圓周運動。可是,實際狀況是這種方法並不可行。由於,你沒法精確的計算出物體作圓周運動的每個座標位置。就算你成功計算出物體作圓周運動的精確座標。OK!你能夠想象那是多麼大的工做量。因此,咱們須要轉變思路,讓計算機去作這種精確的計算問題。bash

圖片描述

上圖展現了從圓的函數表達式到圓的參數方程之間的轉換過程。理解不理解都沒有關係,總之你要明白,最終咱們將 x, y 與 sin 和 cos 扯上關係了。而圓的參數方程就表示的是一個圓。這樣咱們想要讓一個物體作圓周運動,就只須要讓計算機本身去來計算每一幀物體所對應的座標值。而咱們所須要作的只是簡單的改變θ值。有多簡單呢,由於根據sin,cos函數的週期性只須要每一幀自增一個值或自減一個值。具體代碼以下:函數

window.onload = function(){
               var canvas = document.getElementById('canvas'),
                   context = canvas.getContext('2d');

               var ball = new Ball();

               var angle = 0, // 旋轉的角度
                   centerX = canvas.width/2,
                   centerY = canvas.height/2,
                   radius = 100, // 定義半徑
                   speed = 0.05; // 每幀旋轉角度的增長值

               (function drawFrame(){
                   window.requestAnimationFrame(drawFrame, canvas);
                   context.clearRect(0,0,canvas.width, canvas.height);

                   //centerX, centerY 的做用是讓球繞畫布中心旋轉
                   ball.x = centerX + Math.sin(angle)*radius;
                   ball.y = centerY + Math.cos(angle)*radius;

                   //角度增長
                   angle += speed;
                   ball.draw(context);
               }());
           }

效果圖學習

圖片描述

ok,本身動手試試吧!看看是否是球體繞着畫布中心作着圓周運動呢!這裏咱們須要的條件比較多 angle 和 Radius,在後面的章節中咱們將介紹如何只經過 angle 就實現圓周運動。爲了更容易理解,我勸你最好複習一下中學的知識,哈哈!!!動畫

2.橢圓運動

橢圓和正圓的不一樣之處能夠這樣理解:正圓半徑在x軸和y軸上的距離是相同的,都是Radius.而橢圓則是不一樣的,咱們用a, b 表示。spa

圖片描述

具體到代碼裏,就是半徑不一樣了唄!是否是so easy,上代碼:3d

window.onload = function(){
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');
            var ball = new Ball();
            
            var centerX = canvas.width/2,
                centerY = canvas.height/2,
                angle = 0,
                radiusX = 50,
                radiusY = 100,
                speed = 0.05;
            
                ball.x = centerX;
                ball.y = centerY;
                
             context.fillStyle = "rgba(0,0,0,.01)"; 
            (function drawFrame(){
                window.requestAnimationFrame(drawFrame,canvas);
                context.fillRect(0,0,canvas.width,canvas.height);
                
                //當radius的值相等時爲圓周運動
                //當radius的值不想等是爲橢圓運動
                ball.x = centerX + Math.sin(angle)*radiusX; //radiusX = 50
                ball.y = centerY + Math.cos(angle)*radiusY; //radiusY = 100
                angle += speed;
                
                ball.draw(context);
            })();
        }

爲了讓橢圓的效果看起來更加明顯,代替clearRect採用fillRect是小球的運動造成尾跡。rest

圖片描述

3、兩點之間的距離

按理來講,連點之間的距離是不會用到三角函數的。可是,其實兩點間的距離公式是能夠經過勾股定理推出來的,因此這裏直接就把他歸到三角函數裏。
這裏就不畫示意圖了直接給你個公式好了(原諒我偷個懶),假設有兩個點, a(x1, y1), b(x2, y2)。那麼怎樣求它們之間的距離呢!公式以下:code

dx = x2 - x1;
    dy = y2 - y1;
    distance = Math.sqrt(dx*dx + dy*dy); //這不就是勾股定理

這裏給你個小的Demo,代碼以下:blog

<canvas id="canvas" width="500" height="500" style="background:#000;">
           your browser not support canvas!
       </canvas>
       <p id="log"></p>
       <script src="../js/utils.js"></script>
       <script>
       window.onload = function(){
               var canvas = document.getElementById('canvas');
               var log = document.getElementById('log');
               var mouse = utils.captureMouse(canvas);
               var context = canvas.getContext('2d');

               //中心位置建立一個方塊
               var rect = {
                   x:canvas.width/2,
                   y:canvas.height/2
               };

               (function drawFrame(){
                   window.requestAnimationFrame(drawFrame,canvas);
                   context.clearRect(0,0,canvas.width,canvas.height);

                   var dx = mouse.x - rect.x;
                   var dy = mouse.y - rect.y;
                   var dis = Math.sqrt(dx*dx + dy*dy);

                   //畫方塊
                   context.fillStyle = '#ffffff';
                   context.fillRect(rect.x-2,rect.y-2,4,4);
                   //畫線
                   context.save();
                   context.strokeStyle = '#ffffff';
                   context.beginPath()
                   context.moveTo(rect.x,rect.y);
                   context.lineTo(mouse.x,mouse.y);
                   context.closePath();
                   context.stroke();
                   context.restore();
                   //顯示距離
                   log.style.left = (mouse.x + rect.x)/2 + 'px';
                   log.style.top = (mouse.y + rect.y)/2 + 'px';
                   log.innerHTML = dis;
               })();
           }
    </script>

效果圖

圖片描述

4、總結

## 角度旋轉
    dx = mouse.x - object.x;
    dy = mouse.y - object.y;
    object.rotation = Math.atan2(dy,dx)*180/Math.PI

    ## 平滑運動
       value = center + Math.sin(angle)*range;
       angle += speed;

    ## 正圓運動
       x_position = centerX + Math.sin(angle)*radius;
       y_position = centerY + Math.cos(angle)*radius;
       angle += speed;

    ## 橢圓運動
       x_position = centerX + Math.cos(angle)*radiusX;
       y_position = centerY + Math.sin(angle)*radiusY;
       angle += speed;

    ##兩點間距離
    dx = x2 - x1;
    dy = y2 - y1;
    dist = Math.sqrt(dx*dx + dy*dy);
相關文章
相關標籤/搜索