8.4.2.2_利用最小平移向量使两个物体粘在一起

8.4.2.2_利用最小平移向量使两个物体粘在一起

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>利用最小平移向量使两个物体粘在一起</title>
        <style>
            body{
                background: #fff;
            }
            #canvas{
                background: #eee;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="800" height="600"></canvas>
    </body>
        <!-- 精灵对象 -->
    <script>
        var Sprite = function(name,painter,behaviors){
    
            if(name !== undefined){ this.name = name; }
            if(painter !== undefined){ this.painter = painter; }

            this.top = 0;
            this.left = 0;
            this.width = 10;
            this.height = 10;
            this.velocityX = 0;
            this.velocityY = 0;
            this.visible = true;
            this.animating = false;
            this.behaviors = behaviors || [];

        }

        Sprite.prototype = {
            paint:function(context){
    
                if(this.painter !== undefined && this.visible){
                    this.painter.paint(this,context);
                }
            },
            update:function(context,time){
    
                for(var i=0;i<this.behaviors.length;i++){
                    this.behaviors[i].execute(this,context,time);
                }
            }
        }
    </script>

    <!-- 图像绘制器 -->
    <script>
        var ImagePainter = function (imageUrl){
    
            var self = this;
            this.image = new Image();
            this.loaded = false;
            this.image.src = imageUrl;

            this.image.addEventListener('load',function(){
    
                self.loaded = true;
            },false);

        }
        ImagePainter.prototype ={
            paint:function(sprite,context){
    
                //因为图像绘制器专门负责反复绘制精灵对象所用的图像,所以它并不负责图像的加载
                //这里不能像之间一样不负责加载了,之间是用在requestAnimationFrame中,代码会按帧持续执行,图片早晚都会加载出来,
                //所以这块代码块一定会执行。但是在现在这个程序中,在初始化中只走一次,所以很有可能图片还没有加载完成this.image.complete为false

                    context.drawImage(this.image,sprite.left,sprite.top,sprite.width,sprite.height);

            }
        }
    </script>

    <!-- Vector对象 向量对象 --> 
    <script>
        //坐标系中的向量,以0,0出发,到点x,y,为一个向量,向量长度方向相同为同一个向量
        var Vector = function(x,y){
    
            this.x = x;
            this.y = y;
        };

        Vector.prototype = {
            //得到向量的长度
            getMagnitude:function(){
      
                return Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2));
            },

            //两向量相加得到的新向量
            add:function(anotherVector){
    
                var v = new Vector();
                v.x = this.x + anotherVector.x;
                v.y = this.y + anotherVector.y;
                return v;
            },

            //两向量相减,得到边缘法向量 OA-OB = BA;
            subtract:function(anotherVector){
    
                var v = new Vector();
                v.x = this.x - anotherVector.x;
                v.y = this.y - anotherVector.y;
                return v;
            },

            //两向量的点积,一个向量在别一处向量上的投影,得到的不是一个向量,是投影的长度
            dotProduct:function(anotherVector){
    
                return this.x *anotherVector.x+ this.y*anotherVector.y;
            },

            //得到多边形的边缘向量,即多边形,相邻两点的向量
            edge:function(anotherVector){
    
                return this.subtract(anotherVector);
            },

            //得到垂直于边缘向量的边缘法向量,即投影轴向量
            perpendicular:function(){
    
                var v = new Vector();
                v.x = this.y;
                v.y = 0-this.x;
                return v;
            },

            //得去某向量的单位向量,即方向相同,长度为1的向量,单位向量主要是用来指示方向的
            normalize:function(){
    
                var v = new Vector(0,0);
                var m = this.getMagnitude();
                if(m!=0){ //避免向量为0
                    v.x = this.x/m;
                    v.y = this.y/m;
                }
                return v;
            },

            //得去边缘法向量的单位向量,即投影轴向量的单位方向,表示投影轴的方向
            perpendicularNormal:function(){
    
                var p = this.perpendicular();
                return p.normalize();
            }
        }
    </script>

    <!-- Projection 投影对象 -->
    <script>
        var Projection = function(min,max){
    
            this.min = min;
            this.max = max;
        };

        Projection.prototype = {

            //检测两个多边形在同一个投影轴上的投影是否有重合,重叠返回true
            overlaps:function(projection){
    
                return this.max > projection.min && projection.max >this.min;
            },
            overlap : function(projection){
    
                var minP = 10000;
                if(this.max > projection.min && projection.max >this.min){ //两投影在当前投影轴上发生了重叠
                    var pro1 = Math.abs(this.max - projection.min);
                    var pro2 = Math.abs(projection.max - this.min);
                    var pro3 = Math.abs(this.max - this.min );
                    var pro4 = Math.abs(projection.max - projection.min );


                    return Math.min(pro1,pro2,pro3,pro4);
                }else{
                    return 0;
                }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值