Abstract
- 本篇將探討在一個(gè)出現(xiàn)了一點(diǎn)偏差的圓形臺(tái)球桌內(nèi)臺(tái)球的運(yùn)動(dòng)軌跡。(圓形的臺(tái)球桌什么的本來就很詭異了吧)
I have a ball.
~~I have a table. ~~
Ahhh...
Billi-ard!
- ~~I have a
Python
. ~~
~~I have a H.Cai. ~~
Ahhhhhhh...
Chaoooooooos!
- ~Billi-ard~~
Chaoooooooos
Ahhhhhhh.........
Ahhhhhhhhhh.........
Ahhhhhhhhhhhhhhhh.........
Background
-
臺(tái)球本身是件很有意思的事,球在有限的區(qū)域內(nèi)被桌沿或其他的球反彈,逐漸按照既定的速滾走向既定的方向,將目標(biāo)球擊落袋。
- 假如你把它放進(jìn)物理里,就會(huì)顯得更(
喪)加(心)有(病)趣(狂)。 - 我們將探討一個(gè)球在圓形桌內(nèi)的運(yùn)動(dòng),以及當(dāng)那個(gè)圓并不那么圓時(shí),球在那個(gè)不那么圓的圓桌內(nèi)的運(yùn)動(dòng)。
What a Weird Shape!
- 這個(gè)問題我們也將其簡(jiǎn)化,我們認(rèn)為球在桌上的運(yùn)動(dòng)是無耗散的,可以永遠(yuǎn)地滾下去。
- 同時(shí)我們也認(rèn)為,球在邊緣上的反彈是完美的:
入射與反射角相等
- 當(dāng)球碰到邊緣時(shí),我們將這樣處理他的碰壁和反彈:
...
x_next = self.x[-1] + self.vx * self.dt
y_next = self.y[-1] + self.vy * self.dt
# 下一個(gè)點(diǎn)沒有越界
if x_next ** 2 + (abs(y_next) - self.alpha) ** 2 < 1:
self.x.append(x_next)
self.y.append(y_next)
if abs(self.y[-1]) < 0.001:
self.ps_vx.append(self.vx)
self.ps_x.append(self.x[-1])
# 下個(gè)點(diǎn)成功越界,計(jì)算碰撞點(diǎn)并計(jì)算碰撞后速度
else:
divisor = 2
# 往回走一點(diǎn)點(diǎn)
while divisor <= 2048:
x_next -= (self.vx * self.dt / divisor)
y_next -= (self.vy * self.dt / divisor)
# 當(dāng)下個(gè)點(diǎn)與邊界距離在誤差允許范圍內(nèi)時(shí),跳出 loop
if abs(x_next ** 2 + (abs(y_next) - self.alpha) ** 2 - 1) < 0.00001:
divisor = 10000
# 如果剛剛往回走過了,撤銷那一步,下一次走得再小一點(diǎn)
...
- 碰撞后,我們采用(level.6)矢量操作的方式計(jì)算碰撞后的速度。
- 可以得到軌跡圖:
我可以盯著它看上一天.gif
- 考慮當(dāng)alpha = 0.1時(shí),兩個(gè)僅有微小初始值差異的臺(tái)球的運(yùn)動(dòng)軌跡區(qū)別,弄了張動(dòng)圖,
matplotlib
庫(kù)做了一點(diǎn)微小的貢獻(xiàn)
沖啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊.gif
-
上圖,可以預(yù)見二者分離度將在600以后達(dá)到1上下,也就是說兩個(gè)系統(tǒng)將完全分離,
-
上圖,臺(tái)球十分爭(zhēng)氣地滾得亂七八糟
(逃)
-
alpha = 0.1,可以看到在500s內(nèi)他的偏差都是很小的,只有-6的指數(shù)級(jí)別,但是當(dāng)我們把時(shí)間增加一倍,從500s增加到1000s的時(shí)候:
兩個(gè)小球也幾乎沒有產(chǎn)生大的偏差,那么當(dāng)球桌是個(gè)正圓的時(shí)候呢?
-
兩個(gè)球的分離度幾乎肉眼不可見(廢話!)
Acknowledgements!
-
磊鍋鍋張磊 (就沖著這名字我也得把你從致謝里刪了_(:D」∠)_)