您好,登錄后才能下訂單哦!
不懂用Python實現模擬太陽系運動方法?其實想解決這個問題也不難,下面讓小編帶著大家一起學習怎么去解決,希望大家閱讀完這篇文章后大所收獲。
資源素材
太陽系現在只有8大行星,連太陽一起,一共是9張圖片。
def openSolor(solar): def loadImg(name): str1= os.path.join(basePath, name+ '.png') img= Image.open(str1) solar[name]= img basePath= r'D:\太陽系\素材' # loadImg('sun') loadImg('venus') loadImg('jupiter') loadImg('earth') loadImg('mars') loadImg('mercury') loadImg('neptune') loadImg('pluto') loadImg('uranus') loadImg('saturn')
基本運動原理
每顆行星的運動軌跡都是橢圓的,我們這里用一個參數方程來計算坐標:
x=cos(arc)*a
y=sin(arc)*b
其中,a,b 是橢圓的長軸和短軸,arc是運行角度,x,y是水平面坐標。
先上一張靜態效果圖吧!
參數的設置
為了效果好看,實際參數不可能是真實的。但有幾個關鍵條件至少應該滿足。首先行星順序別弄錯,行星軌道之間的間距不是等距的,而是漸增的。
其次是火星和木星直接有一個小行星帶,所以這兩個行星的軌道之間最好留出一個空隙。還有就是越往外圈的行星,繞行速度越慢。
def initSolar(posList): def getNumber(): return random.randint(0,35)*10 posList['sun']={'pos': (0,360), 'rate': 2, 'scale':1, 'radx': 1, 'layer':360} posList['mercury']={'rate': 0.15, 'radx':500, 'arc': getNumber(), 'rady': 200, 'speed':15} posList['venus']={'rate': 0.2, 'radx':550, 'arc': getNumber(), 'rady': 250, 'speed':10} posList['earth']={'rate': 0.2, 'radx':630, 'arc': getNumber(), 'rady': 320, 'speed':8} posList['mars']={'rate': 0.2, 'radx':740, 'arc': getNumber(), 'rady': 410, 'speed':6} posList['jupiter']={'rate': 0.7, 'radx':1050, 'arc': getNumber(), 'rady': 650, 'speed':4} posList['saturn']={'rate': 1, 'radx':1250, 'arc': getNumber(), 'rady': 800, 'speed':3} posList['uranus']={'rate': 0.3, 'radx':1480, 'arc': getNumber(), 'rady': 970, 'speed':2} posList['neptune']={'rate': 0.3, 'radx':1740, 'arc': getNumber(), 'rady': 1160, 'speed':2}
投影
一般的效果是將行星圍繞太陽的公轉面至于一個水平面上,然后投影到垂直的屏幕上。投影算法不難。
x= math.sin(math.radians(a))* radx+ x0 y= math.cos(math.radians(a))* rady+ y0 showX= x showY= midY- H/(D+y)*y
其中,x,y是公轉平面坐標,showX,showY是投影到垂直平面的坐標。H是平面的高度,D是屏幕到太陽系的距離。
從數據來看,我們的太陽系模型是一個非常小的模型,或者電腦屏幕非常大。因為這兩者實際差不多大,以至于從觀察者的視角就可以出現很明顯的近大遠小效果。從這種效果就可以知道,數據與真實值差別極為巨大。
近大遠小的效果,只與y相關。
data['scale']= (y0+D)/(y+D)
遮擋效果
為了有真實感,行星之間、行星與軌道之間,軌道與太陽之間等等的遮擋效果是最關鍵的。
我們的做法是先畫后半區,再畫太陽,再畫前半區。后半區中,遠日行星先畫;前半區中,近日行星先畫。以保證正確的遮擋效果。
drawOrb(img, solar, posList, 0, 90, True) pasteSolor(img, solar, posList) drawOrb(img, solar, posList, 90, 180, False)
比較復雜一點的是行星與自身軌道之間的遮擋關系。必須實現一線穿一球的效果才好看。而且穿球位置不是固定不變的。這里,我們根據行星所在角度的不同,將軌道拆分為兩半來畫。
一部分軌道是被行星遮擋的,另一部分軌道遮擋行星,但留一些空間,以實現比較自然的穿球效果。
drawArc(arc1, arc) rate= posList[name]['rate']* posList[name]['scale'] pic= solarImg[name].resize(effect.tupleRound(effect.tupleMul(solarImg[name].size, rate)), Image.ANTIALIAS) pos= effect.tupleRound(effect.tupleAdd(posList[name]['pos'], effect.tupleMul(pic.size, -0.5))) r, g, b, alpha= pic.split() img.paste(pic, pos, mask= alpha) # 穿球點,隨arc不同而不同 # 90度位置,在中心穿球, # 越接近0或180度,越接近球邊緣 # 根據這種性質,采用cos來模擬 darc= abs(round(math.cos(math.radians(arc))*solarImg[name].size[1]*rate/50)) # darc= abs(round(math.cos(math.radians(arc))*5)) # print(name, arc, darc) drawArc(arc+darc, arc2)
感謝你能夠認真閱讀完這篇文章,希望小編分享用Python實現模擬太陽系運動方法內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。