Exercise_09:The billiard table

we consider a problem of a ball moving without friction on a perfect billiard table.Between collisions the velocity is constant so we have


After locatingthe collision point,We must next obtain the unit vector normal to the wall at the point of collision,

![](http://latex.codecogs.com/png.latex?\vec n).

It is then useful to calculate the components of ![](http://latex.codecogs.com/png.latex?\vec vi)parallel and perpendicular to the wall.These are just

![](http://latex.codecogs.com/png.latex?\vec v_{i,\bot}=(\vec v_i\cdot\vec n)\vec n)
![](http://latex.codecogs.com/png.latex?\vec v_{i,\parallel}=\vec vi-\vec v_{i,\bot})

Hence,the velocity after reflection from the wall is

![](http://latex.codecogs.com/png.latex?\vec v_{f,\bot}=-\vec v_{i,\bot})
![](http://latex.codecogs.com/png.latex?\vec v_{f,\parallel}=\vec v_{i,\parallel})

code

#coding:utf-8
import pylab as pl
import numpy as np
import math


class tabel:
    def __init__(self, x0=0.2, y0=0, vx0=-0.2, vy0=-0.5, dtstep=0.001, total_time=50):
        self.x = [x0]
        self.y = [y0]
        self.vx = [vx0]
        self.vy = [vy0]
        self.time = total_time
        self.t = [0]
        self.dt = dtstep
        self.xbound=[-1]
        self.y1bound=[0]
        self.y2bound=[0]


    def run(self):
        for i in range(int(self.time / self.dt)):
            self.x.append(self.x[i]+self.vx[i]*self.dt)
            self.y.append(self.y[i] + self.vy[i] * self.dt)
            self.vx.append(self.vx[i])
            self.vy.append(self.vy[i])
            if (self.x[i+1]**2+self.y[i+1]**2>1):
                xtry=(self.x[i]+self.x[i+1])/2
                ytry=(self.y[i]+self.y[i+1])/2
                cos=xtry/(xtry**2+ytry**2)**0.5
                sin=ytry/(xtry**2+ytry**2)**0.5
                verticalx=-(self.vx[i]*cos+self.vy[i]*sin)*cos
                verticaly=-(self.vx[i]*cos+self.vy[i]*sin)*sin
                #parallelx=self.vx*sin**2-sin*cos*self.vy
               # parallely=self.vy*cos**2-self.vx*cos*sin
                parallelx=self.vx[i]+verticalx
                parallely=self.vy[i]+verticaly
                self.vx[i+1]=verticalx+parallelx
                self.vy[i+1]=verticaly+parallely
                #利用向量變換得到反彈后的速度vx和vy

                if (xtry**2+ytry**2>1):
                    self.x[i+1]=xtry
                    self.y[i+1]=ytry
                    continue
                else:
                    self.x[i]=xtry
                    self.x[i]=ytry
                    continue

    def bound(self):
        self.xbound= [-1]
        self.y1bound = [0]
        self.y2bound = [0]
        dx = 0.001
        for i in range (2000):
            self.xbound.append(self.xbound[i]+dx)
            self.y1bound.append((1-self.xbound[i+1]**2)**0.5)
            self.y2bound.append(-(1-self.xbound[i+1]**2)**0.5)
    def show(self):
        pl.plot(self.x,self.y,'.',label='tra')
        pl.plot(self.xbound,self.y1bound,'--',label='bound')
        pl.plot(self.xbound,self.y2bound,'--',label='bound')
        pl.xlabel(u'x')
        pl.ylabel(u'y')
a=tabel()
a.run()
a.bound()
a.show()
pl.show()

得到圖像如下圖所示

t=50蜒滩,單位圓下反彈
t=100诗舰,單位圓下反彈

phase space plot

考慮到在兩半圓間增加寬為2α的矩形她肯,并得到動畫,代碼如下

#coding:utf-8
import pylab as pl
import numpy as np
import math
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import animation
#用于制作動畫
class tabel:
    def __init__(self, x0=0.2, y0=0, vx0=0.1, vy0=0.3, dtstep=0.01, total_time=300,alpha=0.1):
        self.x = [x0]
        self.y = [y0]
        self.vx = [vx0]
        self.vy = [vy0]
        self.time = total_time
        self.t = [0]
        self.dt = dtstep
        self.xbound=[-1]
        self.y1bound=[0]
        self.y2bound=[0]
        self.alpha=alpha
    def run(self):
        for i in range(int(self.time / self.dt)):
            self.x.append(self.x[i]+self.vx[i]*self.dt)
            self.y.append(self.y[i] + self.vy[i] * self.dt)
            self.vx.append(self.vx[i])
            self.vy.append(self.vy[i])
            self.t.append(self.t[i]+self.dt)
            if( self.y[i]>=self.alpha):
                if (self.x[i+1]**2+(self.y[i+1]-self.alpha)**2>1):
                    xtry = self.x[i] + self.vx[i]*self.dt/200
                    ytry= self.y[i]+self.vy[i]*self.dt/200
                    dtrebound=self.dt/200
                    while(xtry**2+(ytry-self.alpha)**2<=1):
                        xtry = xtry + self.vx[i] * self.dt / 200
                        ytry = ytry + self.vy[i] * self.dt / 200
                        dtrebound=dtrebound+self.dt/100
                    self.t.append(self.t[-1]+dtrebound)
                    cos=xtry/(xtry**2+(ytry-self.alpha)**2)**0.5
                    sin=(ytry-self.alpha)/(xtry**2+(ytry-self.alpha)**2)**0.5
                    verticalx=-(self.vx[i]*cos+self.vy[i]*sin)*cos
                    verticaly=-(self.vx[i]*cos+self.vy[i]*sin)*sin
                    parallelx=self.vx[i]+verticalx
                    parallely=self.vy[i]+verticaly
                    self.vx[i + 1] = verticalx + parallelx
                    self.vy[i + 1] = verticaly + parallely#利用向量變換得到反彈后的速度vx和vy
                    self.x[i+1]=xtry
                    self.y[i+1]=ytry
            elif(self.y[i]<self.alpha and self.y[i]>-self.alpha):
                if (abs(self.x[i+1])>1):
                    xtry = self.x[i] + self.vx[i]*self.dt/100
                    ytry= self.y[i]+self.vy[i]*self.dt/100
                    dtrebound=self.dt/100
                    while(abs(xtry)<=1):
                        xtry = xtry + self.vx[i] * self.dt / 200
                        ytry = ytry + self.vy[i] * self.dt / 200
                        dtrebound=dtrebound+self.dt/100
                    self.vx[i+1]=-self.vx[i]
                    self.vy[i+1]=self.vy[i]
            elif(self.y[i]<-self.alpha ):
                if(self.x[i+1]**2+(self.y[i+1]+self.alpha)**2>1):
                    xtry = self.x[i] + self.vx[i] * self.dt / 200
                    ytry = self.y[i] + self.vy[i] * self.dt / 200
                    dtrebound = self.dt / 100
                    while (xtry ** 2 + (ytry + self.alpha) ** 2 <=1):
                        xtry = xtry + self.vx[i] * self.dt / 200
                        ytry = ytry + self.vy[i] * self.dt / 200
                        dtrebound = dtrebound + self.dt / 200
                    cos = xtry / (xtry ** 2 + (ytry+self.alpha) ** 2) ** 0.5
                    sin = (ytry+self.alpha)/ (xtry ** 2 + (ytry+self.alpha) ** 2) ** 0.5
                    verticalx = -(self.vx[i] * cos + self.vy[i] * sin) * cos
                    verticaly = -(self.vx[i] * cos + self.vy[i] * sin) * sin
                    parallelx = self.vx[i] + verticalx
                    parallely = self.vy[i] + verticaly
                    self.vx[i + 1] = verticalx + parallelx
                    self.vy[i + 1] = verticaly + parallely
                    self.x[i + 1] = xtry
                    self.y[i + 1] = ytry
    def bound(self):
        self.xbound= [-1]
        self.y1bound = [self.alpha]
        self.y2bound = [-self.alpha]
        dx = 0.001
        for i in range (2000):
            self.xbound.append(self.xbound[i]+dx)
            self.y1bound.append(self.alpha+(1-self.xbound[i+1]**2)**0.5)
            self.y2bound.append(-self.alpha-(1-self.xbound[i+1]**2)**0.5)
    def show(self):
        pl.plot(self.x,self.y,'-',label='tra',linewidth=0.1)
        pl.plot(self.xbound,self.y1bound,'--')
        pl.plot(self.xbound,self.y2bound,'--')
        pl.xlabel(u'x')
        pl.ylabel(u'y')
        pl.ylim(-1.1,1.1)
        pl.xlim(-1.1,1.1)
        pl.axis('equal')
        pl.show()

    def drawtrajectory(self):

        fig = plt.figure()
        ax = plt.axes(title=('Stadium with $\\alpha$ = 0.1, - divergence of two trajectories'),
                      aspect='equal', autoscale_on=False, xlim=(-1.1, 1.1), ylim=(-1.1, 1.1),
                      xlabel=('x'),
                      ylabel=('y'))


        line1 = ax.plot([], [], 'b:')  # 初始化數(shù)據(jù)次洼,line是軌跡蹭劈,point是軌跡的頭部
        point1 = ax.plot([], [], 'bo', markersize=10)

        images = []

        def init():  # 該函數(shù)用于初始化動畫

            line1 = ax.plot([], [], 'b:', markersize=8)
            point1 = ax.plot([], [], 'bo', markersize=10)
            bound1 = ax.plot([], [], 'k.', markersize=1)
            bound2 = ax.plot([], [], 'k.', markersize=1)
            return line1, point1, bound1, bound2

        def anmi(i):  # anmi函數(shù)用于每一幀的數(shù)據(jù)更新酿傍,i是幀數(shù)。
            ax.clear()
            bound1 = ax.plot(self.xbound, self.y1bound, 'k.', markersize=1)
            bound2 = ax.plot(self.xbound, self.y2bound, 'k.', markersize=1)
            line1 = ax.plot(self.x[0:20* i], self.y[0:20 * i], 'b:', markersize=8)
            point1 = ax.plot(self.x[20 * i - 1:20 * i], self.y[20 * i - 1:20 * i], 'bo', markersize=10)
            return line1, point1, bound1, bound2

        anmi = animation.FuncAnimation(fig, anmi, init_func=init, frames=500, interval=1, blit=False, repeat=False, )
        plt.show()


a=tabel()
a.run()
a.bound()
a.show
a.drawtrajectory()

得到下圖

α=0.1

得到動畫如圖

動畫.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踪区,一起剝皮案震驚了整個(gè)濱河市昆烁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缎岗,老刑警劉巖静尼,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異传泊,居然都是意外死亡鼠渺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門眷细,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拦盹,“玉大人,你說我怎么就攤上這事溪椎∑沼撸” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵池磁,是天一觀的道長奔害。 經(jīng)常有香客問我,道長地熄,這世上最難降的妖魔是什么华临? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮端考,結(jié)果婚禮上拍柒,老公的妹妹穿的比我還像新娘己莺。我一直安慰自己示绊,他們只是感情好惶看,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著裂明,像睡著了一般椿浓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天扳碍,我揣著相機(jī)與錄音提岔,去河邊找鬼。 笑死笋敞,一個(gè)胖子當(dāng)著我的面吹牛碱蒙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播夯巷,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼赛惩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了趁餐?” 一聲冷哼從身側(cè)響起喷兼,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澎怒,沒想到半個(gè)月后褒搔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阶牍,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喷面,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了走孽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惧辈。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖磕瓷,靈堂內(nèi)的尸體忽然破棺而出盒齿,到底是詐尸還是另有隱情,我是刑警寧澤困食,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布边翁,位于F島的核電站,受9級特大地震影響硕盹,放射性物質(zhì)發(fā)生泄漏符匾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一瘩例、第九天 我趴在偏房一處隱蔽的房頂上張望啊胶。 院中可真熱鬧,春花似錦垛贤、人聲如沸焰坪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽某饰。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間黔漂,已是汗流浹背碧浊。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘟仿,地道東北人箱锐。 一個(gè)月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像劳较,于是被迫代替她去往敵國和親驹止。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 云天黯黯观蜗,含雨春風(fēng)波滟滟臊恋。 白雪連枝,漫舞飛花一徑溪墓捻。 芳塵幾許抖仅,眉葉新妝搖玉露。 淺草蟲飛砖第,人盡黃昏鳥倦歸撤卢。
    木子夕顏閱讀 541評論 2 10
  • 【達(dá)康兔嘰持續(xù)撩沙( ?? ?)】 “...其實(shí)...達(dá)康...我只是覺得你這個(gè)樣子太可愛了,別人看見你我會...
    Cristiansen閱讀 195評論 0 0