什么是向量
向量通常指一個有長度有方向的量。向量使所有的移動和空間行為更容易理解和在代碼中實現。向量可以相加,縮放,旋轉,指向某物體。
在javascript中,一個方向和長度(即向量)在二維空間中可以用橫坐標x和縱坐標y表示。
上圖中有4個不同的向量及其x和y分量(左上角為原點{x:0,y:0},這里的向量代表方向、長度,而不是位置。
向量長度
向量的方向由x、y分量表示,可以根據x、y坐標用勾股定理來表示長度。
length = Math.sqrt(x*x + y*y);
一個橫坐標( x = -3 ),縱坐標( y = 3 )的向量,利用勾股定理計算長度:
length = Math.sqrt(-3*-3 + 3*3); //length 約為 4.24
在javascript數學函數中,角是以弧度( radian )為單位,不是角度( degree )。1弧度是弧長和半徑相等的弧,圓的周長:2*Math.PI*R(R為半徑),圓的弧度:2*Math.PI
弧度和角度轉化
degrees 角度 radians 弧度 degrees = radians * 180/Math.PI 角度弧度乘於180再除於PI radians = degrees * Math.PI/180 弧度等於角度度乘於PI再除於180 //角度轉弧度 var degToRad = function(deg){ return deg * (Math.PI/180); } //弧度轉角度 var radToDeg = function(rad){ return rad * (180/Math.PI); }
向量的運算
1. 加、減:可以通過加減向量的x,y坐標來實現向量的相加或相減
給飛行的皮球加上一個重力向量,讓它真實的下落
把兩個碰撞物體的向量加在一起,計算逼真的碰撞反饋
給宇宙飛船增加火箭推力的向量,讓宇宙飛船移動
2. 縮放:按照一定比例的縮放向量的x,y坐標,可以縮小或放大向量的長度
反復以略小於1的向量縮放移動向量,讓對應物體緩慢的停下來
將大炮的方向向量擴大,作為一個發射炮彈的初始向量
3. 標准化:有時需要將一個向量變為單位長度,單位長度的向量叫單位向量
定向噴射的方向
斜坡的傾斜方向
大炮的發射方向
4. 旋轉:以任意角度來旋轉一個向量,可以指向任意一個想要的方向
是一個對象始終指向另一個
更改一個虛擬的噴射引擎的推力方向
根據發射器的方向改變投射體的初始發射方向
5. 點乘:點乘給兩個向量之間的角度的余弦,或者點乘提示兩個向量的方向相近程度。點乘的結果在 -1 到 1 之間變化。
向量的方向相同:點積 = 1
向量的夾角是45度:點積 = 0.5
向量的夾角是90度:點積 = 0
向量的夾角是180度:點積 = -1
創建一個javascript向量對象
var vector2d = function (x, y) { var vec = { vx: x, vy: y, // 縮放 scale: function (scale) { vec.vx *= scale; vec.vy *= scale; }, //加 另一個向量 add: function (vec2) { vec.vx += vec2.vx; vec.vy += vec2.vy; }, //減 另一個向量 sub: function (vec2) { vec.vx -= vec2.vx; vec.vy -= vec2.vy; }, //相反方向 negate: function () { vec.vx = -vec.vx; vec.vy = -vec.vy; }, //向量長度 length: function () { return Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy); }, //向量長度的平方 lengthSquared: function () { return vec.vx * vec.vx + vec.vy * vec.vy; }, //標准化 normalize: function () { var len = Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy); if (len) { vec.vx /= len; vec.vy /= len; } return len; }, //旋轉 rotate: function (angle) { var vx = vec.vx, vy = vec.vy, cosVal = Math.cos(angle), sinVal = Math.sin(angle); vec.vx = vx * cosVal - vy * sinVal; vec.vy = vx * sinVal + vy * cosVal; }, //調試 toString: function () { return '(' + vec.vx.toFixed(3) + ',' + vec.vy.toFixed(3) + ')'; } }; return vec; };