2013-01-11 88 views
1

我目前正在嘗試爲一個軸對齊和定向的邊界框添加一個重疊測試器,但該解決方案似乎只在OBB的角度介於-10和+10之間時才能正確工作。當角度接近+90度時,碰撞區域似乎首先移動到OBB的右半部分,然後變得不存在。在90到270之間,我無法獲得重疊,然後當它回到360時,該區域再次準確地進行註冊。分離軸定理問題

關於這個問題的任何亮點都會很棒。我正在使用正X來增加CCW 0度。

乾杯。

編輯:做了更多的研究,並意識到投影到另一個載體需要的不僅僅是一個點積。可以任何一個給我一個正確的版本的下面的檢查軸方法之一非常漂亮請:)

編輯2:其實只是一個點產品應該做的,因爲投影向量是單位長度。

public static bool overlapAABB_OBB(AABB a, OBB o) 
    { 
     float rads = MathHelper.ToRadians(-o.angle); 
     T = Vector2.Subtract(o.position, a.position); 
     Ax.X = 1; 
     Ax.Y = 0; 
     Ay.X = 0; 
     Ay.Y = 1; 
     Ox.X = (float)Math.Cos(rads); 
     Ox.Y = (float)Math.Sin(rads); 
     Oy.X = -Ox.Y; 
     Oy.Y = Ox.X; 
     if (checkAX(a, o) && 
      checkAY(a, o) && 
      checkOX(a, o) && 
      checkOY(a, o)) 
      return true; 
     else 
      return false; 
    } 

    private static bool checkAX(AABB a, OBB o) 
    { 
     float TAx = Vector2.Dot(T, Ax); 
     float WoOxAx = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax); 
     float HoOyAx = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax); 
     if (TAx > a.halfWidth + WoOxAx + HoOyAx) 
      return false; 
     else 
      return true; 
    } 

    private static bool checkAY(AABB a, OBB o) 
    { 
     float TAy = Vector2.Dot(T, Ay); 
     float WoOxAy = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ay); 
     float HoOyAy = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ay); 
     if (TAy > a.halfHeight + WoOxAy + HoOyAy) 
      return false; 
     else 
      return true; 
    } 

    private static bool checkOX(AABB a, OBB o) 
    { 
     float TOx = Vector2.Dot(T, Ox); 
     float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox); 
     float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox); 
     if (TOx > o.halfHeight + WaAxOx + HaAyOx) 
      return false; 
     else 
      return true; 
    } 

    private static bool checkOY(AABB a, OBB o) 
    { 
     float TOy = Vector2.Dot(T, Oy); 
     float WaAxOy = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Oy); 
     float HaAyOy = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Oy); 
     if (TOy > o.halfHeight + WaAxOy + HaAyOy) 
      return false; 
     else 
      return true; 
    } 

回答

1

我在GameDev.stackexchange上發佈了問題,並從rraallvv那裏得到了解決這個問題的答案。

當兩個向量之間的角度大於90º時,點積是負的,爲使代碼正常工作,您需要獲取點積的絕對值。

//... 
private static bool checkAX(AABB a, OBB o) 
{ 
    float TAx = Math.Abs(Vector2.Dot(T, Ax)); 
    float WoOxAx = Math.Abs(Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax)); 
    float HoOyAx = Math.Abs(Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax)); 
    if (TAx > a.halfWidth + WoOxAx + HoOyAx) 
     return false; 
    else 
     return true; 
} 
//... 

這也適用於checkAYcheckOX,並checkOY

0

除了由Mazk1985提供的修復程序,有在checkOX()函數拼寫錯誤。 o.halfHeight應該是o.halfWidth,如下所示:

private static bool checkOX(AABB a, OBB o) 
{ 
    float TOx = Vector2.Dot(T, Ox); 
    float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox); 
    float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox); 
    if (TOx > o.halfWidth + WaAxOx + HaAyOx) 
     return false; 
    else 
     return true; 
}