2013-03-06 48 views
2

在我的libgdx遊戲中,我對地圖和玩家對象有3D BoundingBoxes和Spheres。我想計算它們是否相互碰撞以便正確地模擬這些物體的運動。我可以使用什麼方法來計算這些對象是否相互碰撞/相交?libgdx中BoundingBox和Sphere之間的碰撞檢測

回答

3

您可以使用下面的方法:

public static boolean intersectsWith(BoundingBox boundingBox, Sphere sphere) { 
    float dmin = 0; 

    Vector3 center = sphere.center; 
    Vector3 bmin = boundingBox.getMin(); 
    Vector3 bmax = boundingBox.getMax(); 

    if (center.x < bmin.x) { 
     dmin += Math.pow(center.x - bmin.x, 2); 
    } else if (center.x > bmax.x) { 
     dmin += Math.pow(center.x - bmax.x, 2); 
    } 

    if (center.y < bmin.y) { 
     dmin += Math.pow(center.y - bmin.y, 2); 
    } else if (center.y > bmax.y) { 
     dmin += Math.pow(center.y - bmax.y, 2); 
    } 

    if (center.z < bmin.z) { 
     dmin += Math.pow(center.z - bmin.z, 2); 
    } else if (center.z > bmax.z) { 
     dmin += Math.pow(center.z - bmax.z, 2); 
    } 

    return dmin <= Math.pow(sphere.radius, 2); 
} 

它之後

由吉姆·帕特 從「圖形寶石」,科學出版社爲箱型球相交測試 的簡單方法建模, 1990

可在此處找到示例C代碼:http://www.realtimerendering.com/resources/GraphicsGems/gems/BoxSphere.c

+0

您提供的鏈接已死亡;這就是爲什麼我們不鏈接到外部網站。 – Krythic 2015-11-24 23:50:33

+1

@Krythic固定。這就是爲什麼我們使用Google ...;) – nerdinand 2015-11-25 12:34:39

1

以上答案僅適用於AABB(軸對齊邊界框)。該方法雖然簡潔美觀。所以我把它擴大到包括一般的包圍盒。波紋管是提供與上述相同算法的最小代碼。在下面的代碼中,邊界框由中心和3個方向矢量R,S和T指定。每個代表框的主邊的方向和長度。

struct OBBox{ 
    vector3 center; 
    vector3 S; // representing side s. 
    vector3 R; 
    vector3 T; 
    /* s, r, and t take -1 or +1 representing a corner along side S, R, and T correspondingly. If one of s, r, or t is 0 then middle of corresponding edge of the non-zero side is returned. If 2 of them are 0, then middle of the plane of the corresponding side is returned. */ 
    vector3 getCorner(int s, int r, int t) 
    { 
     return center + (s*S + r*R + t*T)/2.0; 
    } 

} 

public static boolean intersectsWith(OBBox bbox, Sphere sphere){ 
    float dmin = 0.; 

    vector3 center = sphere.center; 
    float centerS = center.S; 
    float centerR = center.R; 
    float centerT = center.T; 

    vector3 bminS = bbox.getCorner(-1, 0, 0); 
    vector3 bmaxS = bbox.getCorner(1, 0, 0); 
    vector3 bminR = bbox.getCorner(0, -1, 0); 
    vector3 bmaxR = bbox.getCorner(0, 1, 0); 
    vector3 bminT = bbox.getCorner(0, 0, -1); 
    vector3 bmaxT = bbox.getCorner(0, 0, 1); 

    if(centerS < bminS.S) { 
     dmin += (centerS-bminS).(centerS-minS); // . means 3d dot product. 
    else if(centerS > bmaxS) 
     dmin += (centerS-bmaxS).(centerS-bmaxS); 
    } 

    if(centerR < bminR.R) { 
     dmin += (centerR-bminR).(centerR-minR); 
    else if(centerR > bmaxR.R) 
     dmin += (centerR-bmaxR).(centerR-bmaxR); 
    } 

    if(centerT < bminT.T) { 
     dmin += (centerT-bminT).(centerT-minT); 
    else if(centerT > bmaxT) 
     dmin += (centerT-bmaxT).(centerT-bmaxT); 
    } 

    return dmin <= (sphere.radius).(sphere.radius); 
}