『壹』 求python三體建模代碼
三體模型
1. 代碼
現在為了把之前的代碼延伸到三體系統,需要給常數增加一些東西——增加第三體的質量、位置和速率向量。把第三恆星的質量視作和太陽的質量等同。
#Mass of the Third Starm3=1.0 #Third Star#Position of the Third Starr3=[0,1,0] #mr3=sci.array(r3,dtype='float64')#Velocity of the Third Starv3=[0,-0.01,0]v3=sci.array(v3,dtype='float64')
需要更新代碼中質心和質心速率的公式。#Update COM formular_com=(m1*r1+m2*r2+m3*r3)/(m1+m2+m3)#Update velocity of COM formulav_com=(m1*v1+m2*v2+m3*v3)/(m1+m2+m3)
對一個三體系統來說,需要修改運動方程使之包括另一物體施加的額外引力。因此,需要在RHS上,對問題中每一對物體施加力的其他物體增加一個力項。在三體系統的情況下,一個物體會受到其餘兩個物體施加的力的影響並因此在RHS上出現兩個力項。數學上可表示為:
為在代碼中反映這些變化,需要為odeint求解器創建一個新函數。
def ThreeBodyEquations(w,t,G,m1,m2,m3): r1=w[:3] r2=w[3:6] r3=w[6:9] v1=w[9:12] v2=w[12:15] v3=w[15:18] r12=sci.linalg.norm(r2-r1) r13=sci.linalg.norm(r3-r1) r23=sci.linalg.norm(r3-r2) dv1bydt=K1*m2*(r2-r1)/r12**3+K1*m3*(r3-r1)/r13**3 dv2bydt=K1*m1*(r1-r2)/r12**3+K1*m3*(r3-r2)/r23**3 dv3bydt=K1*m1*(r1-r3)/r13**3+K1*m2*(r2-r3)/r23**3 dr1bydt=K2*v1 dr2bydt=K2*v2 dr3bydt=K2*v3 r12_derivs=sci.concatenate((dr1bydt,dr2bydt)) r_derivs=sci.concatenate((r12_derivs,dr3bydt)) v12_derivs=sci.concatenate((dv1bydt,dv2bydt)) v_derivs=sci.concatenate((v12_derivs,dv3bydt)) derivs=sci.concatenate((r_derivs,v_derivs)) return derivs
最後,調用odeint函數並向其提供上述函數連同初始條件。#Package initial parametersinit_params=sci.array([r1,r2,r3,v1,v2,v3]) #Initial parametersinit_params=init_params.flatten() #Flatten to make 1D arraytime_span=sci.linspace(0,20,500) #20 orbital periods and 500 points#Run the ODE solverimport scipy.integratethree_body_sol=sci.integrate.odeint(ThreeBodyEquations,init_params,time_span,args=(G,m1,m2,m3))
『貳』 用python做一個地球圍繞太陽轉的圖形
平台: python2.7.10 + wxpython 3.0.2
#!/usr/bin/env python
#-*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
__version__ = '0.1'
app_title = 'Temperature Translator - {}'.format(__version__)
class TempTranslator(wx.Frame):
def __init__(self, parent=None, size=(620, 200), title=app_title):
super(TempTranslator, self).__init__(parent, size=size, title=title)
self.SetMinSize(self.GetSize())
self.panel = wx.Panel(self)
self.init_layout()
self.panel.Layout()
self.Centre(wx.BOTH)
self.Show()
def init_layout(self):
font = self.GetFont()
font.SetWeight(wx.BOLD)
font.SetPointSize(15)
self.panel.SetFont(font)
vbox = wx.BoxSizer(wx.VERTICAL)
self.add_label(vbox, f2c=True)
self.f_tc1, self.c_tc1 = self.add_input(vbox, f2c=True)
self.f_tc1.Bind(wx.EVT_TEXT, self.on_f_text)
line = wx.StaticLine(self.panel, -1, style=wx.LI_HORIZONTAL)
style = wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP
vbox.Add(line, 0, style, 5)
self.add_label(vbox, f2c=False)
self.c_tc2, self.f_tc2 = self.add_input(vbox, f2c=False)
self.c_tc2.Bind(wx.EVT_TEXT, self.on_c_text)
self.panel.SetSizer(vbox)
def add_label(self, vbox, f2c=True):
if f2c:
text1 = 'Fahrenheit'
text2 = 'Celsius'
else:
text1 = 'Celsius'
text2 = 'Fahrenheit'
hbox = wx.BoxSizer(wx.HORIZONTAL)
label = wx.StaticText(self.panel, -1, text1, size=(-1, 30),
style=wx.ALIGN_CENTER)
hbox.Add(label, 1, wx.EXPAND, 10)
label = wx.StaticText(self.panel, -1, text2, size=(-1, 30),
style=wx.ALIGN_CENTER)
hbox.Add(label, 1, wx.EXPAND, 10)
vbox.Add(hbox, 0, wx.EXPAND, 10)
def add_input(self, vbox, f2c=True):
hbox = wx.BoxSizer(wx.HORIZONTAL)
tc1 = wx.TextCtrl(self.panel, -1, size=(260, 40), style=wx.TE_CENTER)
tc1.Bind(wx.EVT_TEXT, self.on_f_text)
label = wx.StaticText(self.panel, -1, ' = ')
tc2 = wx.TextCtrl(self.panel, -1, size=(260, 40), style=wx.TE_CENTER)
hbox.Add(tc1, 1, wx.EXPAND, 10)
hbox.Add(label, 0, wx.ALL | wx.EXPAND, 10)
hbox.Add(tc2, 1, wx.EXPAND, 10)
vbox.Add(hbox, 1, wx.EXPAND, 10)
return tc1, tc2
def on_f_text(self, evt):
f = self.f_tc1.GetValue()
self.c_tc1.SetValue('{}'.format(self.f2c(f)))
def on_c_text(self, evt):
c = self.c_tc2.GetValue()
self.f_tc2.SetValue('{}'.format(self.c2f(c)))
def f2c(self, f):
return (float(f) - 32) / 1.8 if f else ''
def c2f(self, c):
return float(c) * 1.8 + 32 if c else ''
if __name__ == '__main__':
app = wx.App()
TempTranslator()
app.MainLoop()
『叄』 現代計算機是如何計算圓周率的
可以用編程語言計算。以下是python語言
pi = 0.0
N = 100
for i in range(N):
pi += (1/pow(16,i) * ( 4/(8*i +1) -2/(8*i+4)-1/(8*i+5) -1/(8*i +6) ) )
print('圓周率為{:.10f}'.format(pi))
請把以上代碼拷進python語言開發環境里運行,結果如下(下圖是使用python開發環境Spyder運行上述代碼的結果):圓周率為3.1415926536.
(3)python太陽系代碼擴展閱讀
電子計算機的出現使π值計算有了突飛猛進的發展。1949年,美國製造的世上首部電腦-ENIAC(Electronic Numerical Integrator And Computer)在阿伯丁試驗場啟用了。
次年,里特韋斯納、馮紐曼和梅卓普利斯利用這部電腦,計算出π的2037個小數位。這部電腦只用了70小時就完成了這項工作,扣除插入打孔卡所花的時間,等於平均兩分鍾算出一位數。
五年後,IBM NORC(海軍兵器研究計算機)只用了13分鍾,就算出π的3089個小數位。科技不斷進步,電腦的運算速度也越來越快,在60年代至70年代,隨著美、英、法的電腦科學家不斷地進行電腦上的競爭,π的值也越來越精確。
在1973年,Jean Guilloud和Martin Bouyer以電腦CDC 7600發現了π的第一百萬個小數位。
在1976年,新的突破出現了。薩拉明(Eugene Salamin)發表了一條新的公式,那是一條二次收斂算則,也就是說每經過一次計算,有效數字就會倍增。
高斯以前也發現了一條類似的公式,但十分復雜,在那沒有電腦的時代是不可行的。這演算法被稱為布倫特-薩拉明(或薩拉明-布倫特)演演算法,亦稱高斯-勒讓德演演算法。
1989年美國哥倫比亞大學研究人員用克雷-2型(Cray-2)和IBM-3090/VF型巨型電子計算機計算出π值小數點後4.8億位數,後又繼續算到小數點後10.1億位數。
2010年1月7日——法國工程師法布里斯·貝拉將圓周率算到小數點後27000億位。2010年8月30日——日本計算機奇才近藤茂利用家用計算機和雲計算相結合,計算出圓周率到小數點後5萬億位。
2011年10月16日,日本長野縣飯田市公司職員近藤茂利用家中電腦將圓周率計算到小數點後10萬億位,刷新了2010年8月由他自己創下的5萬億位吉尼斯世界紀錄。56歲的近藤茂使用的是自己組裝的計算機,從10月起開始計算,花費約一年時間刷新了紀錄。
『肆』 python 類的成員是列表的話設置_init_時候命名該如何命名
你想描述什麼?
def getPlanet(self,xxx):?
還是fun2獲取不到self.
『伍』 python太陽花怎麼做
1.打開界面:
打開Python shell界面,具體是Python語言的IDLE軟體腳本。
『陸』 用python,turtle繪制數字,如繪制260這三個數字,同時要求每個數字填不同的顏色
1、雙擊打開pycharm開發工具,在已新建的項目中新建python文件,輸入文件名稱。
『柒』 arcgis9.3中python如何編程太陽入射角餘弦
可以使用math模塊,導入math後,使用math函數中相關函數就可以了。
『捌』 怎樣用python畫圖
思路:
1. 確定好需要畫的圖。
2. 創建一個畫布,用來畫你需要的圖。
(1)畫布大小,可以使用默認大小,也可以自定義畫布大小。
(2)畫布背景色bgcolor()。
(3)確定起點位置。
3. 畫筆的設置。
(1)畫筆的大小,顏色。
(2)畫筆運行屬性。
二、定義畫布參數
importturtleast
t.screensize(width=None,heigh=None,bg=None)#以像素為單位,參數分別為畫布的寬,高,背景色
t.screensize()#返回默認大小(400,300)
t.Screen()#也是表示默認畫布大小,注意S大寫
t.setup(w=0.5,h=0.75,startx=None,starty=None)#w,h為整數是表示像素,為小數時表示占據電腦屏幕的比例
#startx,starty坐標表示矩形窗口左上角頂點的位置,默認為屏幕中心位置
三、定義畫筆
1、畫筆的狀態
在畫布上默認有一個坐標原點為畫布中心的坐標軸,坐標原點上有一隻面朝x軸正方向小烏龜。這里我們描述小烏龜時使用了兩個詞語:坐標原點(位置),面朝x軸正方向(方向),turtle繪圖中,就是使用位置方向描述小烏龜(畫筆)的狀態。
2、畫筆的屬性
畫筆(畫筆的屬性,顏色、畫線的寬度)
(1)turtle.pensize():設置畫筆的寬度;
(2)turtle.pencolor():沒有參數傳入,返回當前畫筆顏色,傳入參數設置畫筆顏色,可以是字元串如"green","red",也可以是RGB 3元組;
>>>pencolor('brown')
>>>tup=(0.2,0.8,0.55)
>>>pencolor(tup)
>>>pencolor()
'#33cc8c'
(3)turtle.speed(speed):設置畫筆移動速度,畫筆繪制的速度范圍[0,10]整數,數字越大越快。
相關推薦:《Python入門教程》
3、繪圖命令
操縱海龜繪圖有著許多的命令,這些命令可以劃分為3種:一種為運動命令,一種為畫筆控制命令,還有一種是全局控制命令。
(1)畫筆運動命令:
(3)全局控制命令:
四、命令詳解
turtle.circle(radius,extent=None,steps=None)
描述:以給定半徑畫圓
參數:
radius(半徑);半徑為正(負),表示圓心在畫筆的左邊(右邊)畫圓;
extent(弧度) (optional);
steps (optional) (做半徑為radius的圓的內切正多邊形,多邊形邊數為steps);
舉例:
circle(50)#整圓;
circle(50,steps=3)#三角形;
circle(120,180)#半圓
五、繪圖舉例
(1)菱形太陽花
importturtleast#turtle庫是python的內部庫,直接import使用即可
defdraw_diamond(turt):
foriinrange(1,3):
turt.forward(100)#向前走100步
希望我的回答對你有幫助
『玖』 如何用python繪制☀類似這樣的太陽
使用turtle庫繪制,也可以花20讓我給你繪制
『拾』 使用Matplotlib模擬Python中的三維太陽系
編程的一個用途是通過模擬來幫助我們理解真實世界。這一技術被應用於科學、金融和許多其他定量領域。只要控制現實世界屬性的「規則」是已知的,你就可以編寫一個計算機程序來 探索 你遵循這些規則所得到的結果。在本文中,您將 用Python模擬三維太陽系 使用流行的可視化庫Matplotlib
在這篇文章,你將能夠用Python創建你自己的3D太陽系,你可以用你想要的多少太陽和行星。下面是一個簡單的太陽系的一個例子,它有一個太陽和兩個行星:
你還可以打開動畫地板上的二維投影,更好地展示太陽系的三維本質。下面是同樣的太陽系模擬,包括2D投影:
下面是這篇文章的概要,以便您知道接下來會發生什麼:
在本文中,您將使用面向對象的編程和Matplotlib。如果您希望閱讀更多關於任何一個主題的內容,您可以閱讀:
讓我們從使用Matplotlib在Python中模擬一個3D太陽系開始。
太陽系中的太陽、行星和其他天體都是運動中的天體,它們相互吸引。引力在任何兩個物體之間施加。
如果這兩個對象有大量M_1和M_2是距離r然後,你可以用以下公式計算它們之間的引力:
常數G是一個引力常數。您將看到如何在模擬的版本中忽略這個常量,在本文中,您將使用任意單位的質量和距離,而不是kg和m。
一旦你知道了兩個物體之間的引力,你就可以計算出加速度。a每個物體都是由於這種引力而經歷的,使用以下公式:
使用這個加速度,你可以調整運動物體的速度。當速度發生變化時,速度和方向都會發生變化。
當用Python模擬一個三維太陽系時,你需要用三維空間來表示太陽系。因此,這個3D空間中的每個點都可以用三個數字來表示, x -, y -和 z -坐標。例如,如果你想把太陽放在太陽系的中心,你可以將太陽的位置表示為 (0, 0, 0) .
您還需要在3D空間中表示向量。矢量具有大小和方向。你需要像速度、加速度和力這樣的量的矢量,因為這些量都有一個方向和一個震級。
在本文中,我將不詳細討論向量代數。相反,我將陳述您需要的任何結果。你可以讀到更多關於向量與向量代數如果你願意的話。
為了在代碼中更容易地處理向量,您可以創建一個類來處理它們。編寫這個類將作為對類和面向對象編程的快速刷新。你可以讀到用Python進行面向對象的編程如果你覺得你需要一個更徹底的解釋。雖然您也可以創建一個類來處理3D空間中的點,但這並不是必要的,在本文中我也不會創建一個類。
如果您熟悉向量和面向對象編程,可以跳過本節,只需在定義 Vector 班級。
創建一個名為 vectors.py 中,您將定義 Vector 班級。您將使用此腳本定義類並對其進行測試。然後,可以刪除最後的測試代碼,只需在這個腳本中保留類定義:
這個 __init__() 方法的 Vector 類有三個參數,表示每個軸上的值。每個參數的默認值為 0 表示該軸的原點。雖然我們不喜歡在Python中使用單個字母名稱, x , y ,和 z 是恰當的,因為它們代表了數學中常用的笛卡爾坐標系的術語。
您還定義了兩個Dunder方法來將對象表示為一個字元串:
在代碼段的末尾,您可以更多地了解這兩種類型的字元串表示之間的差異。Python編碼書第9章 .
測試代碼塊的輸出如下:
在Python項目中的這個3D太陽系中,如果 Vector 類是可索引的,以便您可以使用 [] 帶有索引以提取其中一個值的符號。使用當前形式的類,如果添加 print(test[0]) 在您的腳本中,您將得到一個 TypeError 說 Vector 對象不可訂閱。您可以通過向類定義中添加另一個Dud方法來修復這個問題:
通過定義 __getitem__() ,你做了 Vector 可索引的類。向量中的第一項是 x 的價值。 y 的價值。 z 。任何其他索引都會引發錯誤。測試代碼塊的輸出如下:
test[0] 返迴向量中的第一個項, x .
可以定義類的對象的加法和減法。 __add__() 和 __sub__() DunderMethod.這些方法將使您能夠使用 + 和 - 執行這些操作的符號。如果沒有這些Dud方法,則使用 + 和 - 提出 TypeError .
若要添加或減去兩個向量,可以分別添加或減去向量的每個元素:
雙管齊下 __add__() 和 __sub__() 返回另一個 Vector 對象,每個元素等於兩個原始向量中相應元素的加減。輸出如下:
對於乘法和除法,您也可以這樣做,盡管在處理向量時,這些操作需要更多的注意。
在處理向量時,不能僅僅引用「乘法」,因為有不同類型的「乘法」。在這個項目中,你只需要標量乘法。標量乘法是指向量與標量相乘(標量有一個數量級,但沒有方向)。但是,在本小節中,您還將定義點積兩個向量。你想用 * 運算符,既適用於標量乘法,也適用於點積。因此,可以定義 __mul__() DunderMethod:
使用 * 運算符將取決於第二個操作數,即 * 符號,是標量或向量。如果由參數表示的第二個操作數 other ,是類型的 Vector ,計算了點積。但是,如果 other 是類型的 int 或 float ,返回的結果是一個新的 Vector ,按比例調整。
以上代碼的輸出如下:
如果您想要標量乘法,則需要標量乘法。 後 這個 * 象徵。如果您試圖運行該語句 3*Vector(3, 5, 9) 相反, TypeError 將被提高,因為 Vector 類不是用於使用的有效操作數。 * 帶有類型的對象 int .
兩個向量是分不開的。但是,可以將向量除以標量。您可以使用 / 運算符 Vector 如果定義 __truep__() DunderMethod:
產出如下:
如果你有一個向量(x,y,z),您可以找到它的震級使用表達式(x^2+y^2+z^2)。你也可以規范化向量。歸一化給出一個方向相同但大小為 1 。您可以通過將向量的每個元素除以矢量的大小來計算歸一化向量。
可以定義兩個新方法來完成 Vector 班級:
測試代碼提供了以下輸出:
第三個輸出給出了歸一化向量的大小,表明它的大小是 1 .
根據使用的IDE或其他工具,在分割時可能會收到警告 self.x , self.y ,和 self.z ,如在 __truep__() 和 normalize() 。您不需要擔心這個問題,但是如果您想要修復它,可以通過更改 __init__() 簽署下列任何一項:
或
這兩個選項都讓IDE知道參數應該是浮動的。在第二個選項中,您使用類型暗示來實現。
您現在可以刪除此腳本末尾的測試代碼,以便您在 vectors.py 是類的定義。
現在,你可以開始研究Python中的3D太陽系了。您將創建兩個主要類:
你將使用Matplotlib來創建和可視化太陽系。您可以在終端中使用以下內容來安裝Matplotlib:
或
這個 Axes3D Matplotlib中的物體將「託管」太陽系。如果您使用過Matplotlib,並且主要使用了2D繪圖,那麼您將使用(有意或不知情的) Axes 對象。 Axes3D 的3D等效 Axes ,顧名思義!
現在是開始編寫和測試這些類的時候了。您可以創建兩個新文件:
接下來,您將開始處理 SolarSystem 班級。
您將在整個項目中使用任意單元。這意味著,與其用米作為距離,而用公斤作為質量,你將使用沒有單位的數量。參數 size 用於定義包含太陽系的立方體的大小:
定義 SolarSystem 類的 __init__() 方法,其中包含參數。 size 。您還定義了 bodies 屬性。這個屬性是一個空列表,當你稍後創建它們時,它將包含太陽系內的所有天體。這個 add_body() 方法可以用來將軌道天體添加到太陽系中。
下一步是介紹Matplotlib。屬性創建圖形和一組軸。 subplots() 在 matplotlib.pyplot :
你打電話 plt.subplots() ,它返回一個圖形和一組軸。返回的值分配給屬性。 fig 和 ax 。你打電話 plt.subplots() 有以下論點:
您還可以調用該方法。 tight_layout() 。這是 Figure 類在Matplotlib中。此方法減少了圖形邊緣的邊距。
到目前為止,您可以在控制台/REPL中嘗試代碼:
這給出了一組空的三維軸的圖形:
您將使用 size 參數設置此多維數據集的大小。你會回到 SolarSystem 稍後上課。目前,您可以將您的注意力轉向定義 SolarSystemBody 班級。
您可以開始創建 SolarSystemBody 類及其 __init__() 方法。我正在截斷 SolarSystem 下面代碼中的類定義用於顯示。在此代碼塊和以後的代碼塊中,包含 # ... 指出您之前編寫的未顯示的代碼:
中的參數。 __init__() 方法是:
你也叫 add_body() 方法中定義的 SolarSystem 類將這個天體添加到太陽系中。稍後,您將向 __init__() 方法。
中定義另一個方法。 SolarSystemBody 用其當前的位置和速度移動物體:
這個 move() 方法重新定義 position 屬性的 velocity 屬性。我們已經討論過你是如何用任意單位來計算距離和質量的。你也在使用任意的時間單位。每個『時間單位』將是循環的一個迭代,您將使用它來運行模擬。因此, move() 將身體按一次迭代所需的數量移動,這是一個時間單位。
你們已經創建了Matplotlib結構,它將容納太陽系及其所有天體。現在,您可以添加一個 draw() 方法 SolarSystemBody 若要在Matplotlib圖上顯示主體,請執行以下操作。您可以通過繪制一個標記來完成這一任務。
在這樣做之前,您需要在 SolarSystemBody 若要控制將繪制的標記的顏色和大小以表示身體,請執行以下操作:
類屬性 min_display_size 和 display_log_base 設置參數,以確定您將在3D圖上顯示的標記的大小。您設置了一個最小的大小,以便您顯示的標記不太小,即使對於小的身體也是如此。您將使用對數標度將質量轉換為標記大小,並將此對數的基值設置為另一個類屬性。
這個 display_size 屬性中的實例屬性。 __init__() 方法在計算的標記大小和所設置的最小標記大小之間進行選擇。為了在這個項目中確定身體的顯示大小,你要使用它的質量。
您還可以添加 colour 屬性 __init__() ,暫時默認為黑色。
要測試這些新添加的內容,可以在控制台/REPL中嘗試以下內容:
第一次呼叫 body.draw() 在原點繪制物體,因為你使用的是太陽系天體的默認位置。打電話給 body.move() 用一個「時間單位」所需的數量移動身體。因為身體的速度是 (1, 1, 1) ,身體將沿著三個軸中的每一個移動一個單位。第二次呼叫 body.draw() 在第二個位置畫太陽系天體。請注意,當您這樣做時,軸將自動重新排列。您很快就會在主代碼中處理這個問題。
您可以返回到 SolarSystem 通過給太陽系及其天體添加兩種新的方法,將其分類和連接起來: update_all() 和 draw_all() :
這個 update_all() 方法穿過太陽系中的每一個物體,移動並畫出每一個物體。這個 draw_all() 方法使用太陽系的大小設置三軸的限制,並通過 pause() 功能。此方法還清除軸,為下一個繪圖做好准備。
您可以開始構建一個簡單的太陽系,並通過創建一個名為 simple_solar_system.py :
運行此腳本時,您將看到一個黑體從情節的中心移動:
您可以更改三維圖形的透視圖,這樣您就可以直接沿著其中一個軸查看3D軸。可以通過將視圖的方位和仰角設置為 0 在……裡面 SolarSystem.__init__() :
跑動 simple_solar_system.py 現在給出以下觀點:
這個 x -軸現在垂直於你的屏幕。因為你在2D顯示器上顯示一個3D視圖,所以你總是有一個方向與你用來顯示圖形的2D平面垂直。這一限制使得很難區分物體何時沿該軸運動。你可以通過改變身體的速度 simple_solar_system.py 到 (1, 0, 0) 並再次運行腳本。身體似乎是靜止的,因為它只是沿著軸移動,從你的屏幕出來!
您可以通過根據它的不同更改標記的大小來改進三維可視化。 x -協調。靠近您的對象看起來更大,而更遠的對象看起來更小。您可以對 draw() 方法中的 SolarSystemBody 班級:
self.position[0] 表示身體的位置。 x -軸,即垂直於屏幕的軸。因子 30 除以是一個任意因素,您可以使用它來控制您希望這種效果有多強。
在本教程的後面,您還將添加另一個功能,將有助於可視化的三維運動的恆星和行星。
你有一個太陽系,裡面有可以移動的物體。到目前為止,如果您只有一個身體,那麼代碼可以正常工作。但那不是一個非常有趣的太陽系!如果你有兩個或兩個以上的物體,它們就會通過相互的引力相互作用。
在這篇文章的開頭,我簡要回顧了你需要處理兩個物體之間的引力的物理。由於在這個項目中使用的是任意單位,所以可以忽略引力常數 G 簡單地計算出由於兩個物體之間的重力而產生的力,如:
一旦你知道了兩個物體之間的力,因為F=ma,您可以計算出每個對象必須使用的加速度:
一旦你知道加速度,你就可以改變物體的速度。
您可以添加兩個新方法,一個在 SolarSystemBody 另一個在 SolarSystem ,計算出任何兩個物體之間的力和加速度,並穿過太陽系中的所有物體,並計算它們之間的相互作用。
第一種方法計算出兩個物體之間的引力,計算每個物體的加速度,並改變兩個物體的速度。如果您願意,可以將這些任務分為三種方法,但在本例中,我將將這些任務放在 SolarSystemBody :
accelerate_e_to_gravity() 對類型的對象調用。 SolarSystemBody 需要另一個 SolarSystemBody 身體作為一種爭論。參數 self 和 other 代表兩個身體相互作用。此方法的步驟如下:
現在你可以計算出任何兩個天體之間的相互作用,你可以計算出太陽系中所有天體之間的相互作用。你可以把你的注意力轉移到 SolarSystem 類的類:
這個 calculate_all_body_interactions() 方法貫穿太陽系的所有天體。每個天體與太陽系中的其他天體相互作用:
現在,您已經准備好創建一個簡單的太陽系,並測試您到目前為止編寫的代碼。
在這個項目中,您將關注創建兩種類型的天體之一:太陽和行星。您可以為這些機構創建兩個類。新類繼承自 SolarSystemBody :
這個 Sun 類的默認質量為10,000個單位,並將顏色設置為黃色。使用字元串 'yellow' ,這是Matplotlib中的有效顏色。
在 Planet 類創建一個 itertools.cycle 對象有三種顏色。在這種情況下,這三種顏色是紅色、綠色和藍色。你可以使用你想要的任何RGB顏色,也可以使用任意數量的顏色。在這個類中,使用帶有RGB值的元組來定義顏色,而不是使用顏色名稱的字元串。這也是在Matplotlib中定義顏色的有效方法。使用 next() 每當你創建一個新的行星時。
您還將默認質量設置為10個單元。
現在,你可以創建一個太陽系,其中一個太陽和兩個行星在 simple_solar_system.py :
在這個腳本中,您創建了一個太陽和兩個行星。你把太陽和行星分配給變數 sun 和 planets ,但這並不是嚴格要求的,因為 Sun 和 Planet 對象被創建,它們被添加到 solar_system 你不需要直接引用它們。
你用一個 while 循環來運行模擬。循環在每次迭代中執行三個操作。運行此腳本時,將獲得以下動畫:
它起作用了,算是吧。你可以看到太陽錨定在這個太陽系的中心,行星受到太陽引力的影響。除了行星在包含你電腦屏幕的平面上的運動(這些是 y -和 z --軸),你也可以看到行星越來越大,因為它們也在 x -軸,垂直於屏幕。
然而,你可能已經注意到行星的一些奇怪的行為。當它們被安排在太陽後面時,行星仍然被展示在太陽的前面。這不是數學上的問題--如果你跟蹤行星的位置,你會發現 x -坐標顯示,它們實際上是在太陽後面,正如你所預料的那樣。
這個問題來自Matplotlib在繪圖中繪制對象的方式。Matplotlib按繪制對象的順序將對象按層繪制。因為你在行星之前創造了太陽, Sun 對象放在第一位 solar_system.bodies 並作為底層繪制。您可以通過在行星之後創建太陽來驗證這一事實,在這種情況下,您將看到行星總是出現在太陽後面。
你會希望Matplotlib按照正確的順序繪制太陽系的天體,從最前的那些天體開始。要實現這一點,您可以對 SolarSystem.bodies 的值為基礎的列表。 x -協調每次刷新3D圖形的時間。下面是如何在 update_all() 方法 SolarSystem :
使用List方法 sort 帶著 key 參數來定義要用於排序列表的規則。這個 lambda 函數設置此規則。在本例中,您使用的值是 position[0] 表示 x -協調。因此,每次你打電話 update_all() 在模擬中 while 循環中,根據其沿 x -軸心。
運行 simple_solar_system.py 現在的腳本如下:
現在,你可以想像行星的軌道,就像它們圍繞太陽運行一樣。不斷變化的大小顯示了它們的 x -位置,當行星在太陽後面時,它們被隱藏在視線之外!
最後,你也可以移除軸線和網格,這樣你在模擬中看到的就是太陽和行星。可以通過添加對Matplotlib的調用來做到這一點。 axis() 方法 SolarSystem.draw_all() :
模擬現在看起來是這樣的:
使用Matplotlib對Python中的一個三維太陽系進行的模擬現在已經完成。在下一節中,您將添加一個功能,允許您查看 XY -模擬底部的飛機。這有助於可視化太陽系中物體的三維動力學。
在Python的三維太陽系模擬中,為了幫助可視化身體的運動,您可以在動畫的「地板」上添加一個2D投影。這個2D投影將顯示物體在 XY -飛機。要實現這一點,您需要將另一個繪圖添加到顯示動畫的相同軸上,並且只需在 x -和 y -坐標。你可以錨定 z -與圖形底部協調,使2D投影顯示在動畫的地板上。
您可以首先將一個新參數添加到 __init__() 方法的 SolarSystem 班級:
新參數 projection_2d ,默認為 False ,將允許您在兩個可視化選項之間切換。如果 projection_2d 是 False 動畫將只顯示身體在3D中移動,沒有軸和網格,就像你最後看到的結果一樣。
讓我們開始做一些改變 projection_2d 是 True :
您所做的更改如下:
您還需要在 simple_solar_system.py 打開2D投影:
模擬現在看起來如下:
的二維投影 XY -平面使它更容易跟隨軌道物體的路徑。
我們將用Python完成另一個三維太陽系的模擬。您將使用已經定義的類來模擬雙星系統。創建一個名為 binary_star_system.py 創造兩個太陽和兩個行星: