2017-03-18 98 views
-1

我知道這並不完全是找到碰撞點的「正確」方法,因爲可能有1或2(儘管因爲碰撞是有保證的,所以不是0),但我想試試它看看它是如何展開的,所以我創建了3個球體和2個點(每個點應該表示兩個球體之間的碰撞點)都離開了他們應該的位置,就好像我得到的方向矢量是它需要的是相反的......這裏是我的Lua代碼:尋找2個球體的碰撞點

local function getDist(s1, s2) 
     local s1_Pos = (s2.Position - s1.Position).unit * s1.Size.X * .5 
     local s2_Pos = (s1.Position - s2.Position).unit * s2.Size.X * .5 
     return s1_Pos:Lerp(s2_Pos, .5) 
    end 
  1. 什麼是錯的代碼?
  2. 如何找到2個球體的碰撞點?

我在StackOverflow上閱讀了幾個問題,但大多數都是無關緊要的,或者只是沒有意義。

回答

0

p0,p1是中心和r0,r1是半徑然後

if (|p1-p0|<=r0+r1) // collision if centers closer then sum of radiuses 
{ 
p = p0 + ((p1-p0) * r0/(r0+r1)); // weighted linear interpolation 
} 

碰撞點不是中心之間的中點,而是改變爲更靠近小球。這個方程只有精確的if (r0+r1 == |p1-p0|),否則兩個球體重疊,方程返回重疊體積的中點。

所以如果p0=(x0,y0,z0), p1=(x1,y1,z1)你可以重寫:

if ((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)+(z1-z0)*(z1-z0)<=(r0+r1)*(r0+r1)) 
{ 
x = x0 + (((x1-x0)*r0)/(r0+r1)); 
y = y0 + (((y1-y0)*r0)/(r0+r1)); 
z = z0 + (((z1-z0)*r0)/(r0+r1)); 
// (x,y,z) is your collision point 
} 

您還可以得到overlapp圓圈包圍的重疊量。它是上面計算的中心(x,y,z)和垂直於矢量(p1-p0)的圓,它也定義了兩個球體的切割平面。所以如果你需要這個圓圈內的點,使用基圓矢量和簡單的參數或圓/圓盤的隱式函數。欲瞭解更多信息,請參閱:

+0

謝謝,好像它的工作:d雖然你是如何得到的X輕微的解釋,Y,Z將嚴重讚賞,因爲我是一個有點困惑,爲什麼例如x0有兩次,x1有一次,r0有兩次,r1有一次,所有這一切,但頂線是可以理解的,看看如果兩個球體中心之間的距離是相同或小於2個球體的半徑(這可以以更簡單的方式完成(p0-p1).Magnitude <= r0 + r1) – KapKing

+0

@KapKing它被稱爲線性插值'a = a0 + (a1-a0)* t'如果't = 0'比'a = a0' 'a = a1',如果't'介於'a'之間也在'a0,a1'之間。現在't'被稱爲參數,並且在距離爲'<0.0,1.0>'的時候,因爲你得到了半徑和距離,所以你需要以某種方式轉換它:'t = r0 /(r0 + r1)'這會讓你't'對齊碰撞中點(由'r0,r1'加權) – Spektre

+0

好吧,這似乎清除了一些事情,謝謝。 – KapKing