2013-10-05 34 views
1

在您指出這個問題還有其他答案之前,我已經查看了如果不是全部,大部分其他答案或者類似的問題,還沒有找到我需要的解決方案。如何確定一個矩形的哪一邊與一個圓碰撞

基本上所有我想要做的就是當圓/球碰撞一個矩形時,我想確定碰撞發生在矩形的哪一側。我想知道這一點,以便我可以執行一些更真實的物理,例如如果球擊中矩形的頂部,則反轉爲僅Y速度...而不是兩者。

我試過比較球和矩形的X和Y位置,甚至兩個邊界框的位置......即使球的框底部已經與矩形頂部相交測試......使用'if ball.boundingBox.Bottom> = rectangle.boundingBox.Top'。

我附上了一張圖片來展示我想要達到的目的......以防萬一它有點令人困惑,因爲它沒有詳細說明......紅色看起來像v的是路徑,如果球來了從一側開始,我希望在撞擊時的運動以相反的方式行進,但這取決於矩形的側面,以及球的速度的哪個部分,我將不得不改變...

FYI我也有看着矢量歸...我還沒有使用它之前,所以請原諒我,如果這可以用這個來解決......

感謝v.much閱讀

編輯,因爲我在趕時間,我用了一個不同的圖像,而不是...這仍然顯示我想要實現的行爲,因爲圖上顯示的物理是我想要球的行爲,當它與另一邊...... 鏈接到Image:http://codeincomplete.com/posts/2011/6/12/collision_detection_in_breakout/bounce2.v283.png

回答

4

此代碼可能比你更需要全面,可以重構,以滿足您的需求,但它是一個完整的答案,是靈活的與移動一起移動邊界矩形使用界。

這裏是一個圖形來給出代碼正在做的事情的視覺幫助。 紅圈與黑色矩形相交。想像兩條穿過對角的虛線。如果您知道圓圈所在的兩條線的哪一側,則可以推斷出相撞的邊緣。

enter image description here

首先聲明類範圍內的私有成員

Rectangle CollisionBoxRect; 
Rectangle circleRect; 
Dictionary<string, Vector2> corners; 

在你更新你移動後的圓圈,並設置它的位置和潛在的交叉框的位置,它基本檢查,看是否圓的邊界矩與卷的邊界矩有關。如果是這樣,它會根據碰撞的圓的哪一側以適當的碰撞法線改變球的速度。

if (CollisionBoxRect.Intersects(circleRect)) 
{ 
    ballVelocity = Vector2.Reflect(ballVelocity, GetCollisionNormal(CollisionBoxRect)); 
} 

以下方法支持獲取正確的一面(實際上是正常的)。其中一些方法可以在初始化階段完成一次,如果它們從不改變(如get corner方法);

private Vector2 GetCollisionNormal(Rectangle boxBeingIntersected) 
{ 
    getCorners(boxBeingIntersected); 
    bool isAboveAC = isOnUpperSideOfLine(corners["bottomRight"], corners["topLeft"], getBallCenter()); 
    bool isAboveDB = isOnUpperSideOfLine(corners["topRight"], corners["bottomLeft"], getBallCenter()); 

    if (isAboveAC) 
    { 
     if (isAboveDB) 
     { 
      //top edge has intersected 
      return -Vector2.UnitY; 
     } 
     else 
     { 
      //right edge intersected 
      return Vector2.UnitX; 
     } 
    } 
    else 
    { 
     if (isAboveDB) 
     { 
      //left edge has intersected 
      return -Vector2.UnitX; 
     } 
     else 
     { 
      //bottom edge intersected 
      return Vector2.UnitY; 
     } 
    } 
} 

public bool isOnUpperSideOfLine(Vector2 corner1, Vector2 oppositeCorner, Vector2 ballCenter) 
{ 
    return ((oppositeCorner.X - corner1.X) * (ballCenter.Y - corner1.Y) - (oppositeCorner.Y - corner1.Y) * (ballCenter.X - corner1.X)) > 0; 
} 

private Vector2 getBallCenter() 
{ 
    return new Vector2(circleRect.Location.X + circleRect.Width/2, circleRect.Location.Y + circleRect.Height/2); 
} 

private void getCorners(Rectangle boxToGetFrom) 
{ 
    corners.Clear(); 
    Vector2 tl = new Vector2(boxToGetFrom.X, boxToGetFrom.Y); 
    Vector2 tr = new Vector2(boxToGetFrom.X + boxToGetFrom.Width, boxToGetFrom.Y); 
    Vector2 br = new Vector2(boxToGetFrom.X + boxToGetFrom.Width, boxToGetFrom.Y + boxToGetFrom.Height); 
    Vector2 bl = new Vector2(boxToGetFrom.X, boxToGetFrom.Y + boxToGetFrom.Height); 
    corners.Add("topLeft", tl); 
    corners.Add("topRight", tr); 
    corners.Add("bottomRight", br); 
    corners.Add("bottomLeft", bl); 
} 
+0

哇,非常感謝您深入響應。對不起,我只是意識到,我收到了這篇文章的回覆... 我會看看這個,並嘗試在我的代碼中實現它,因爲我仍然有相同的概率,但我今天才恢復完成此遊戲......我會讓你知道發生了什麼......謝謝你 – 6a6179