javascript canvas 碰撞检测

1.外接图形判别法

1.外接矩形判别法

//先算出小球底部的位置,然后根据它现在的移动速度与当前动画的帧速率,估算出小球在下一帧动画中的位置
ballWillHitLedge:function(ledge){
    var ballRight = ball.left + ball.width,
        ledgeRight = ledge.left + ledge.width,
        ballBottom = ball.top + ball.height,
        nextBallBottomEstimate = ballBottom + ball.velocityY / fps;
    return ballRight > ledge.left && 
            ball.left < ledgeRight &&
            ballBottom < ledge.top &&
            nextBallBottomEstimate > ledge.top;
}

2.外接圆判别法

检测两个圆是否发生碰撞:两个圆心之间的距离是否小于两圆半径之和,小于:碰撞,否则没碰撞

isBallInBucket:function(){
    var ballCenter = {
        x:ball.left + BALL_RADIUS,
        y:ball.top + BALL_RADIUS
    },
    distance = Math.sqrt(
        Math.pow(bucketHitCenter.x - ballCenter.x,2) + 
        Math.pow(bucketHitCenter.y - ballCenter.y,2)
    );
    return distance < BALL_RADIUS + bucketHitRadius;
}

2.碰到墙壁即被弹回的小球

handleEdgeCollisions:function(){
    var bbox = getBoundingBox(ball),
        right = bbox.left + bbox.width,
        bottom = bbox.top + bbox.height;
    if(right > canvas.width || bbox.left < 0){
        velocityX = -velocityX;
        if(right > canvas.width){
            ball.left -= right - canvas.width;
        }
        if(bbox.left < 0){
            ball.left -= bbox.left;
        }
    }
    if(bottom > canvas.height || bbox.top < 0){
        velocityY = -velocityY;
        if(bottom > canvas.height){
            ball.top -= bottom-canvas.height;
        }
        if(bbox.top < 0){
            ball.top -= bbox.top;
        }
    }   
}

3.光线投影法

画一条与物体的速度向量(velocity vector)相重合的线,然后再从另一个待检测的物体出发,绘制第二条线,根据两条线的交点位置来判定是否发生碰撞 。
在小球的飞行过程中,程序不断的擦除并重绘从小球到1,2号交点处的连线。

4.分离轴定理(SAT)与最小平移向量(MTV)

4.1 分离轴定理只适用于凸多边形

数学模型:把受测的两个多边形置于一堵墙前面,用光线照射它们,然后根据其阴影部分是否相交来判断二者有没有相撞。
阴影部分:投影
墙:轴
只要能在任何一条轴上找到互相分离的投影,就说明两个多边形没有发生碰撞,一旦发生了碰撞,肯定在所有的轴上都找不到互相分离的投影。
投影轴的数量等同于多边形的总边数,如三角形和四边形,就要有7个投影轴。
伪代码:

//returns true if the polygon1 and polygon2 have collided
function polygonsCollide(polygon1,polygon2){
    var axes,projection1,projection2;//projection:投射所用
    axes = polygon1.getAxes();
    axes.push(polygon2.getAxes());//axes is an axis array
    for(each axis in axes){
        projection1 = polygon1.project(axis);
        projection2 = polygon2.project(axis);
        if(!projection1.overlaps(projection2))
            return false;//Separation means no collision
    }
    return true;//no separation on any axis means collision
}

问题:

  • 如何确定多边形的各个投影轴
  • 如何将多边形投射到某条分离轴上
  • 如何检测两段投影是否发生重叠

    4.2 圆形与多边形之间的碰撞检测

    只需将圆形投射到一条投影轴上即可,这条轴就是圆心与距其最近的多边形顶点之间的连线。
    还需要将这两个受测物体投射到多边形的各条投影轴上才行。

你可能感兴趣的:(JavaScript,canvas)