2013-04-04 91 views
1

考慮三維太陽系模擬。物理模擬基礎知識

我的模擬循環:

[Calculate new positions]->[Render]->[Calculate new positions]->[Render] etc.... 

這個循環的,比方說,25FPS運行。

我的模擬中的一顆行星非常快地向着太陽行進(在碰撞過程中)。讓我們看看模擬循環:

  1. 位置計算爲行星和太陽(他們還沒有相互碰撞,但彼此非常接近)。
  2. 場景呈現。
  3. 由於FPS不是無限的,在下一次迭代之前會有一個小的停頓。
  4. 位置是計算行星和太陽 - 這是我的問題的關鍵 - 他們沒有相撞,因爲在'小暫停'行星已經'穿過'太陽,他們的位置現在是一個很大的距離。碰撞檢測算法不檢測任何碰撞。

唯一的解決方案,我可以在這裏看到:

  • 提高FPS
  • 下我的行星的速度(降低引力常數?)
  • 有一個獨立的仿真循環比沿着渲染循環運行,但速度更快

對於任何感興趣的人,我使用的是three.js

回答

3

在射擊遊戲中發生射彈。一個解決方案是讓你的運動舞臺沿着前進路徑拍攝一條線段,看看它是否會在下一幀之前觸及任何東西。這假定只有一個對象正在快速移動。我想你也可以在最後的位置和新的位置之間運行一段,儘管我自己並沒有這樣做。我也成功地將我的對撞機定義向前擴展到覆蓋未檢查區域的橢圓。

+0

很高興聽到我並不孤單。感謝DrC。我會解決你的問題。 – JoeRocc 2013-04-04 16:15:55

0

你可以看看兩個物體之間的角度變化,如果這將接近180度或pi弧度,它們很可能會碰撞。 計算兩個物體之間角度的變化可以用線性代數的一點點(使用dot product)來完成:

dx0 = object[i].x - object[j].x; 
dy0 = object[i].y - object[j].y; 
dz0 = object[i].z - object[j].z; 
dx1 = object[i].x + timeStep * object[i].u - object[j].x - timeStep * object[j].u; 
dy1 = object[i].y + timeStep * object[i].v - object[j].y - timeStep * object[j].v; 
dz1 = object[i].z + timeStep * object[i].w - object[j].z - timeStep * object[j].w; 
dangle = acos((dx0 * dx1 + dy0 * dy1 + dz0 * dz1)/(sqrt(dx0 * dx0 + dy0 * dy0 + dz0 * dz0) * sqrt(dx1 * dx1 + dy1 * dy1 + dz1 * dz1))); 

您不必採取反餘弦,因爲COS(懸)將接近-1的吊環接近180度。

我不確定你應該採取哪一個範圍來成功檢測到碰撞,這一部分有點試錯。我認爲這不是碰撞檢測中的唯一步驟,並且在此檢查之後它們會發生碰撞,假定在這個時間步驟中兩個物體以直線和恆定速度移動。 要解決的方程將是一個二次方程,它可以有兩個可能的答案(其中之一是如果他們會相互干擾並在另一側相撞)。但是如果你對它們相撞的確切時間不感興趣,你仍然可以使用判別式來確定是否會發生碰撞。

+0

對於手頭的問題似乎過於複雜。 – Monkeyanator 2013-04-29 14:27:13