如何對球體和長方體進行碰撞檢測?

假設各長方體的邊均與坐標軸平行或者垂直
已知球的球心和半徑,長方體的中心和各個邊長,如何檢測兩者的碰撞呢?


怎樣判斷平面上一個矩形和一個圓形是否有重疊? - Milo Yip 的回答是可以擴展至三維甚至更高維的,據我所知是現存最快且最簡單的方法。

如果需計算接觸法線(contact normal)及滲透深度(penetration depth),可以對上述演算法稍作修改,情況(a)至(c)的接觸法線是u的方向,深度是u的長度減去半徑;(d)要在v-h中找最小分量。


你這樣的長方體術語上叫AABB。這樣的檢測在很多書上都有,網路上也很多,貼一段搬來的代碼

inline float squared(float v) { return v * v; }
bool doesCubeIntersectSphere(vec3 C1, vec3 C2, vec3 S, float R)
{
float dist_squared = R * R;
/* assume C1 and C2 are element-wise sorted, if not, do that now */
if (S.X &< C1.X) dist_squared -= squared(S.X - C1.X); else if (S.X &> C2.X) dist_squared -= squared(S.X - C2.X);
if (S.Y &< C1.Y) dist_squared -= squared(S.Y - C1.Y); else if (S.Y &> C2.Y) dist_squared -= squared(S.Y - C2.Y);
if (S.Z &< C1.Z) dist_squared -= squared(S.Z - C1.Z); else if (S.Z &> C2.Z) dist_squared -= squared(S.Z - C2.Z);
return dist_squared &> 0;
}

上面C1和C2是AABB的對角兩個點的值,S是圓心,R是半徑。


如果只要判斷是否相交是容易的。

計算球心到每個面和頂點的距離。如果任何一個距離大於半徑則不相交,否則有交點。(規定所有面的法線朝外)


{點到面的距離 d = Ax+By+Cz+D

[(A,B,C,D)為平面方程且A*A+B*B+C*C=1]}


感謝 @Milo Yip 指出錯誤。只判斷到面的距離是不夠的,會導致過於保守的結果。因此Milo給出的方法是計算量最優的。


我來答一下,首先解決球體長方體的定位問題,球體不用說了,立方體利用這四個點定位:

每三個點確定一個平面。
球心到三個平面的距離分別為d1,d2,d3;if(d1&>r+ad2&>r+bd3&>r+c)
{
這樣沒有碰
}
else if (任何一面距離小了一點,根據向量abc三個向量的方向與圓心到原點形成的向量方向是否相反判斷球體的位置,若小了,但是在另一側)
{
還是沒有碰
}
else
{
好像就要碰了
}
以上答案,歡迎指正。


推薦閱讀:

謝爾賓斯基三角形能用編程寫出來么?該怎麼寫?
使用目前的高配GPU 如何實時渲染一顆黑洞?
你寫過什麼有趣的程序?
是什麼原因導致中國電影作品特效效果普遍不如歐美電影?
什麼是實時光線追蹤技術?它可能出現在當前的次世代主機上嗎?

TAG:計算機 | 趣味數學 | 計算機圖形學 |