2014-01-13 193 views
8

其实我想检测你的矩形的碰撞在下面的代码段的循环: -检测用矩形的碰撞圈

function checkCollision() { 
    //checking of the Collision 
    if (ry + rh > cy - radius && rx + rw > cx - radius && rx + rw < cx + radius) { 
      dy = -dy; 
    } 
} 

这也是我的代码的一部分: -

var rx = 50; //distance from the x-axis of the Rect. 
var ry = 50; //distance from the y-axis of the Rect. 
var rw = 80; //width of the Rect 
var rh = 30; //Height of the Rect. 

// Distance to moved of the Rect. 
var dx = 2; 
var dy = 2; 

// Center of the circle from the x-axis and y-axis. 
var cx = 105; 
var cy = 135; 
var radius = 16; 
var cx1 = 6; 
var cy1 = 6; 

任何人都可以帮助我弄清楚什么是错的吗?

回答

30

检测圆矩形的碰撞是不平凡的(但没有那么复杂要么)。

@kuroi neko的解决方案是正确的,大概就像代码一样简单。

幸运的是,您不需要完全理解使用命中测试函数的数学理论。

如果你想对函数是如何工作的详细信息,下面是使用4个步骤进行测试,如果一个圆和一个矩形的碰撞描述:

演示:http://jsfiddle.net/m1erickson/n6U8D/

首先,定义一个圆形或矩形

var circle={x:100,y:290,r:10}; 
var rect={x:100,y:100,w:40,h:100}; 

步骤#1:找到垂直&水平(distX /二STY)圆的中心与矩形的中心

var distX = Math.abs(circle.x - rect.x-rect.w/2); 
    var distY = Math.abs(circle.y - rect.y-rect.h/2); 

步骤#2之间的距离:如果该距离大于halfCircle + halfRect更大,则它们被分开得太远要碰撞

if (distX > (rect.w/2 + circle.r)) { return false; } 
    if (distY > (rect.h/2 + circle.r)) { return false; } 

步骤#3:如果该距离小于halfRect然后他们肯定碰撞

if (distX <= (rect.w/2)) { return true; } 
    if (distY <= (rect.h/2)) { return true; } 

步骤4:测试直角拐角处的碰撞。

  • 觉得从矩形中心向任何矩形角落
  • 现在线由圆
  • 的半径延长该行如果圆的中心在该行他们正好是矩形角落碰撞

使用毕达哥拉斯公式来比较圆和中心之间的距离。

var dx=distX-rect.w/2; 
    var dy=distY-rect.h/2; 
    return (dx*dx+dy*dy<=(circle.r*circle.r)); 

继承人的全码:

var circle={x:100,y:290,r:10}; 
var rect={x:100,y:100,w:40,h:100}; 

// return true if the rectangle and circle are colliding 
function RectCircleColliding(circle,rect){ 
    var distX = Math.abs(circle.x - rect.x-rect.w/2); 
    var distY = Math.abs(circle.y - rect.y-rect.h/2); 

    if (distX > (rect.w/2 + circle.r)) { return false; } 
    if (distY > (rect.h/2 + circle.r)) { return false; } 

    if (distX <= (rect.w/2)) { return true; } 
    if (distY <= (rect.h/2)) { return true; } 

    var dx=distX-rect.w/2; 
    var dy=distY-rect.h/2; 
    return (dx*dx+dy*dy<=(circle.r*circle.r)); 
} 
+0

我知道这个解决方案很不错,,,我已经看到了小提琴文件,真正感谢那个家伙@markE ,,但实际上我刚开始HTML5的Canvas ,,它不那么强硬码,,,但都不我需要,,,我竟然有一种类型的乒乓游戏的地方,我必须圆(桨)和矩形(OBJ作为球),那它..之间的碰撞检测!希望你能得到一个简单的解决方案.. !! – Gurjit

+0

PLZ如果你不介意可以编辑我的checkCollision功能..! – Gurjit

+0

@markE这个版本的情况下,更精简你考虑矩形“实”(圆被认为是在矩形内时发生碰撞)。我通过我的[测试小提琴](http://jsfiddle.net/CDLwP/4/)运行它,它像一个魅力。 –

4

这是一个办法做到这一点:

1)找到矩形的角最接近圆心
2)怎么看这个函数接受一个圆相对于角落

定位第三个参数,以允许一个“固体”的矩形和一个简单的轮廓(即,完全位于矩形内部的圆的情况下,是否应被视为一个碰撞)

function collides (rect, circle, collide_inside) 
{ 
    // compute a center-to-center vector 
    var half = { x: rect.w/2, y: rect.h/2 }; 
    var center = { 
     x: circle.x - (rect.x+half.x), 
     y: circle.y - (rect.y+half.y)}; 

    // check circle position inside the rectangle quadrant 
    var side = { 
     x: Math.abs (center.x) - half.x, 
     y: Math.abs (center.y) - half.y}; 
    if (side.x > circle.r || side.y > circle.r) // outside 
     return false; 
    if (side.x < -circle.r && side.y < -circle.r) // inside 
     return collide_inside; 
    if (side.x < 0 || side.y < 0) // intersects side or corner 
     return true; 

    // circle is near the corner 
    return side.x*side.x + side.y*side.y < circle.r*circle.r; 
} 

var rect = { x:50, y:50, w:80, h:30 }; 
var circle = { x:105, y:135, r:16 }; 

if (collides (rect, circle)) { /* bang! */ } 

之间的区别我有第二个函数计算碰撞法线向量,以允许动画处理矩形反弹的圆。 它们一起用作基地this fiddle

function bounces (rect, circle) 
{ 
    // compute a center-to-center vector 
    var half = { x: rect.w/2, y: rect.h/2 }; 
    var center = { 
     x: circle.x - (rect.x+half.x), 
     y: circle.y - (rect.y+half.y)}; 

    // check circle position inside the rectangle quadrant 
    var side = { 
     x: Math.abs (center.x) - half.x, 
     y: Math.abs (center.y) - half.y}; 
    if (side.x > circle.r || side.y > circle.r) // outside 
     return { bounce: false }; 
    if (side.x < -circle.r && side.y < -circle.r) // inside 
     return { bounce: false }; 
    if (side.x < 0 || side.y < 0) // intersects side or corner 
    { 
     var dx = 0, dy = 0; 
     if (Math.abs (side.x) < circle.r && side.y < 0) 
     { 
      dx = center.x*side.x < 0 ? -1 : 1; 
     } 
     else if (Math.abs (side.y) < circle.r && side.x < 0) 
     { 
      dy = center.y*side.y < 0 ? -1 : 1; 
     } 

     return { bounce: true, x:dx, y:dy }; 
    } 
    // circle is near the corner 
    bounce = side.x*side.x + side.y*side.y < circle.r*circle.r; 
    if (!bounce) return { bounce:false } 
    var norm = Math.sqrt (side.x*side.x+side.y*side.y); 
    var dx = center.x < 0 ? -1 : 1; 
    var dy = center.y < 0 ? -1 : 1; 
    return { bounce:true, x: dx*side.x/norm, y: dy*side.y/norm }; 
} 
+0

你能不能给我带来一个简单的解决方案,,,我认为我很难跟进意味着拿起我的代码,但感谢您的努力..! – Gurjit

+0

您现在有一个工作示例。恐怕您需要一些数学背景来了解细节,但您可以将小提琴作为基础,只需全面理解背后的情况即可。 –

+0

我知道这个解决方案并不困难,而且我有点能够遵循它@kuroi neko,但实际上我刚刚开始html5画布,它不是那么艰难的代码,,,但我也不需要,,,我实际上有一种类型的乒乓球游戏,我必须检测圆(桨)和矩形(作为球的obj)之间的碰撞。希望你能得到一个简单的解决方案.. !! – Gurjit

0

我发现我遇到的问题来了与选择的答案。这是我的,我认为运作良好:

function collisionCheckCircleRect(circle, rect) 
{ 
    var distx = Math.abs(circle.x - rect.x); 
    var disty = Math.abs(circle.y - rect.y); 

    if (distx > (rect.width/2 + circle.radius)) { return false; } 
    if (disty > (rect.height/2 + circle.radius)) { return false; } 

    if (distx <= (rect.width/2)) { return true; } 
    if (disty <= (rect.height/2)) { return true; } 

    var hypot = (distx - rect.width/2)*(distx- rect.width/2) + 
         (disty - rect.height/2)*(disty - rect.height/2); 

//console.log(hypot <= (circle.radius*circle.radius)) 
    return (hypot <= (circle.radius*circle.radius)); 
} 
+0

这似乎是错误的:http://jsfiddle.net/n6U8D/283/ – CoderPi

1

一个碰撞检测的近似版本,假设圆实际上是一个正方形。如果圆圈足够小,用户将不会注意到其中的差异。

如果矩形从中心得出:

if(sphere.x + sphere.radius > (rectangle.x - rectangle.width/2) && 
    sphere.x - sphere.radius < (rectangle.x + rectangle.width/2) && 
    sphere.y + sphere.radius > (rectangle.y - rectangle.height/2) && 
    sphere.y - sphere.radius < (rectangle.y + rectangle.height/2)) 
{  
    //collided 
} 

如果矩形从左上角得出:

if(sphere.x + sphere.radius > rectangle.x && 
    sphere.x - sphere.radius < (rectangle.x + rectangle.width) && 
    sphere.y + sphere.radius > rectangle.y && 
    sphere.y - sphere.radius < (rectangle.y + rectangle.height)) 
{ 
    //collided 
} 

,这里是两个版本的的jsfiddle: https://jsfiddle.net/TappT/z5r21nu0/16/

+0

这个答案其实是方矩形碰撞检测,不是圆形,矩形碰撞检测!尝试增加圆的半径并将其移近矩形的其中一个角。 https://jsfiddle.net/z5r21nu0/17/ – Stefnotch