您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)用Python實(shí)習(xí)唯美星空的方法,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
用Python顯示真實(shí)的星空
還是先上圖
本文講怎樣畫出真實(shí)的星空。
預(yù)備知識(shí)
如果想顯示真實(shí)的星空,首先你得有真實(shí)恒星的位置坐標(biāo)和亮度標(biāo)記。它的基本格式如下: {'long': 0.023278328898474372, 'lat': -0.09961466705757636, 'light': 46, 'const': 66}, {'long': 0.024870941840919196, 'lat': 0.2338062439126301, 'light': 55, 'const': 62}, {'long': 0.028107061526797, 'lat': 1.1204335039257496, 'light': 56, 'const': 18}, {'long': 0.03660100303760025, 'lat': 0.5077259659824991, 'light': 21, 'const': 1}, {'long': 0.04004802831028905, 'lat': 1.0323574005393255, 'light': 23, 'const': 18}, {'long': 0.03944444109507185, 'lat': 0.3178583859888262, 'light': 55, 'const': 62}, {'long': 0.040797071265367454, 'lat': -0.488478858963941, 'light': 54, 'const': 74}, {'long': 0.0410661312228549, 'lat': -0.798444499556106, 'light': 39, 'const': 64}, {'long': 0.043800486202076855, 'lat': 0.1945266317121166, 'light': 55, 'const': 66}, {'long': 0.045036755271142, 'lat': 0.804111967609767, 'light': 50, 'const': 1}, {'long': 0.043785947609407745, 'lat': -1.4350775693910554, 'light': 53, 'const': 58}, {'long': 0.04915283505929031, 'lat': -0.2699684886295715, 'light': 49, 'const': 21}, {'long': 0.050498187206605094, 'lat': -0.4851966800391031, 'light': 54, 'const': 74},
每顆星星包含4個(gè)信息:天球經(jīng)度long、天球緯度lat、亮度light(越小越亮)、所屬星座const。
想象所有的星星都鑲嵌在一個(gè)天球上,它們的位置是固定不變的,所以叫做恒星。
星星的坐標(biāo)用經(jīng)緯度來表示,就如同地球上的位置用經(jīng)緯度來表示。當(dāng)?shù)厍蛐D(zhuǎn)時(shí),我們看到的是天球的旋轉(zhuǎn)。
我們所熟悉的北極星,就在非??拷烨虮睒O的位置上。
在天球旋轉(zhuǎn)的過程中,它的位置幾乎不動(dòng)。也就是說北極星的位置幾乎在任何時(shí)候都保持在天空中固定的位置上。之所以能夠用北極星來指示方向,也就是這個(gè)原理。
另外,星空是球形的,想把它顯示在屏幕上,又涉及幾組基本參數(shù)的設(shè)置:
觀測地的經(jīng)緯度
觀測的日期和時(shí)間
觀測者的觀測角度和屏幕大小
這幾組參數(shù)中,關(guān)系是這樣的:觀測地的維度是第一位的,觀測地確定后,所能看到的星空就是確定的(天球傾角),只有在赤道上能夠看到所有的星星,在其它維度都會(huì)有一些星星看不到。
最極端的情況下是在兩極地區(qū),永遠(yuǎn)只能看到半個(gè)天球(即一半數(shù)量的星星)。
觀測地的經(jīng)度、觀測日期和觀測時(shí)間這三者其實(shí)是等價(jià)的,因?yàn)榈厍虻墓D(zhuǎn)和自轉(zhuǎn)對(duì)于遙遠(yuǎn)的星空來說,可以認(rèn)為沒有差別。
當(dāng)觀測點(diǎn)和觀測日期時(shí)間都確定后,理論可以認(rèn)為所能看到的星空大約有全天中半數(shù)的星星。但能夠顯示在屏幕上的星星,則取決于你向哪里觀看以及屏幕有多大。
如果能夠理解上面這些基本知識(shí),請(qǐng)繼續(xù)往下看。
星空計(jì)算
計(jì)算經(jīng)過這樣幾個(gè)步驟:
1、為了便于計(jì)算,首先將每顆星星的經(jīng)緯度轉(zhuǎn)換為xyz的三維坐標(biāo)。在這種轉(zhuǎn)換過程中,我們看到的是正立的天球,北極點(diǎn)向上,南極點(diǎn)在下。
2、將觀測地的緯度引入每顆計(jì)算
3、將觀測地經(jīng)度、觀測日期、觀測時(shí)間三者結(jié)合起來,形成一個(gè)經(jīng)度數(shù)據(jù),引入每顆計(jì)算
4、將觀測者的朝向引入每顆計(jì)算
5、將觀測者的仰角引入每顆計(jì)算
6、向屏幕投影
代碼如下:
def calcStar(stars,Long,Lat,winLong,winLat,eyeDistant): Long= radians(Long) Lat= radians(Lat) winLong= radians(winLong) winLat= radians(winLat) for star in stars: # print(star) # 經(jīng)緯度轉(zhuǎn)換為xyz的三維坐標(biāo) x0= cos(star['long'])* cos(star['lat']) y0= sin(star['long'])* cos(star['lat']) z0= sin(star['lat']) # 觀測地經(jīng)度及日期時(shí)間的合并 x1= x0*cos(Long)- y0*sin(Long) y1= x0*sin(Long)+ y0*cos(Long) z1= z0 # 觀測地緯度 x2= x1* sin(Lat)- z1* cos(Lat) y2= y1; z2= x1* cos(Lat)+ z1* sin(Lat) # 觀測者轉(zhuǎn)身 x3= x2* cos(winLong)+ y2* sin(winLong) y3= -x2* sin(winLong)+ y2* cos(winLong) z3= z2 # 觀測者俯仰 x4= x3* sin(winLat)- z3* cos(winLat) y4= y3 z4= x3* cos(winLat)+ z3* sin(winLat) # 屏幕投影 star['visible']= (z2> 0 and z4>0) star['x']= x4* eyeDistant/z4 star['y']= y4* eyeDistant/z4 star['z']= z4
星星可見的條件是:在地平線之上(z2>0)并且在觀測者面前(z4>0),而可見的星星是否真正顯示在屏幕上的則取決于它是否在屏幕顯示范圍內(nèi)。
顯示代碼如下:
img= Image.new('RGBA', (1280,720), (0,0,120,255)) # 深藍(lán)色天空 draw = ImageDraw.Draw(img) color= (255,255,0,255) # 黃色星星 for star in stars: # 屏幕中心 x= round(-star['y']+ 640) y= round(star['x']+ 360) # 亮度值越小越亮,這里用大小來表示 r= round(6-star['light']/10) if visible(star): # print(x,y) draw.ellipse((x-r, y-r, x+r, y+r), fill=color) img.show()
怎樣將經(jīng)度、觀測日期和觀測時(shí)間結(jié)合起來
這個(gè)問題比想象的復(fù)雜太多。如果想做到真正的精確,會(huì)涉及平太陽日、真太陽日、恒星日、歲差、經(jīng)度與本地時(shí)間的差異,等等很多細(xì)節(jié)。
不過,好在這些誤差并不太大,如果你的目標(biāo)不是科研,并且只考慮近代而不是遠(yuǎn)古和未來,有些誤差即使忽略也沒有太大的影響。
這里我用一個(gè)雖然簡略,但足夠精確的一個(gè)經(jīng)驗(yàn)公式來計(jì)算。輸入觀測地經(jīng)度、觀測日期和時(shí)間,返回一個(gè)所謂的絕對(duì)經(jīng)度,以這個(gè)經(jīng)度作為我們計(jì)算星空位置所使用的經(jīng)度值。
代碼如下:
def getAbsLong(aLong, ayy, amm, add, ahh, amin): # 年的影響忽略 # 月日的影響,首先計(jì)算太陽赤經(jīng) # 春分點(diǎn)3月21日為經(jīng)度0,一年平均365.25天,旋轉(zhuǎn)360度,用插值方法簡單計(jì)算 a= julianDay(ayy, amm, add) b= julianDay(ayy, 3, 21) v= 0- (a-b)/365.25*360 # 因?yàn)槭褂帽镜貢r(shí)間,基本可以忽略經(jīng)度+時(shí)區(qū)的影響(互相抵消) # 時(shí)分的影響,中午12點(diǎn),正對(duì)太陽赤經(jīng),一天24小時(shí),旋轉(zhuǎn)360度,用插值簡單計(jì)算 c= ahh*60+amin d= 12*60 v= v- (c-d)/(24*60)*360 return v
星座連線是怎么來的
星座連線用于輔助我們理解星座形狀。結(jié)構(gòu)很簡單,就是指明一條線關(guān)聯(lián)哪兩個(gè)點(diǎn)。這里不展開了,詳見代碼。
{'star1': 61, 'star2': 4, 'const': 1}, {'star1': 60, 'star2': 61, 'const': 1}, {'star1': 83, 'star2': 60, 'const': 1}, {'star1': 83, 'star2': 109, 'const': 1}, {'star1': 61, 'star2': 58, 'const': 1}, {'star1': 58, 'star2': 22, 'const': 1}, {'star1': 22, 'star2': 3097, 'const': 1}, {'star1': 3097, 'star2': 3097, 'const': 1}, {'star1': 3097, 'star2': 3088, 'const': 1}, {'star1': 3007, 'star2': 3090, 'const': 1}, {'star1': 142, 'star2': 61, 'const': 1},
關(guān)于用Python實(shí)習(xí)唯美星空的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。