javascript中的“向量”

  什么是向量  

  向量通常指一个有长度有方向的量。向量使所有的移动和空间行为更容易理解和在代码中实现。向量可以相加,缩放,旋转,指向某物体。 

  在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;
};

 

 

 

 

 

 

  

 

posted @ 2015-07-21 17:42  eyeear  阅读(4289)  评论(0编辑  收藏  举报