什么是向量
向量通常指一个有长度有方向的量。向量使所有的移动和空间行为更容易理解和在代码中实现。向量可以相加,缩放,旋转,指向某物体。
在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; };