2014-01-13 195 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