本文講怎樣畫出真實的星空。
每顆星星包含4個資訊:天球經度long、天球緯度lat、亮度light(越小越亮)、所屬星座const。
想象所有的星星都鑲嵌在乙個天球上,它們的位置是固定不變的,所以叫做恆星。星星的座標用經緯度來表示,就如同地球上的位置用經緯度來表示。當地球旋轉時,我們看到的是天球的旋轉。我們所熟悉的北極星,就在非常靠近天球北極的位置上。在天球旋轉的過程中,它的位置幾乎不動。也就是說北極星的位置幾乎在任何時候都保持在天空中固定的位置上。之所以能夠用北極星來指示方向,也就是這個原理。
另外,星空是球形的,想把它顯示在螢幕上,又涉及幾組基本引數的設定:
觀測地的經緯度
觀測的日期和時間
觀測者的觀測角度和螢幕大小
這幾組引數中,關係是這樣的:觀測地的維度是第一位的,觀測地確定後,所能看到的星空就是確定的(天球傾角),只有在赤道上能夠看到所有的星星,在其它維度都會有一些星星看不到。最極端的情況下是在兩極地區,永遠只能看到半個天球(即一半數量的星星)。觀測地的經度、觀測日期和觀測時間這三者其實是等價的,因為地球的公轉和自轉對於遙遠的星空來說,可以認為沒有差別。當觀測點和觀測日期時間都確定後,理論可以認為所能看到的星空大約有全天中半數的星星。但能夠顯示在螢幕上的星星,則取決於你向****以及螢幕有多大。
如果能夠理解上面這些基本知識,請繼續往下看。
計算經過這樣幾個步驟:
為了便於計算,首先將每顆星星的經緯度轉換為xyz的三維座標。在這種轉換過程中,我們看到的是正立的天球,北極點向上,南極點在下。
將觀測地的緯度引入每顆計算
將觀測地經度、觀測日期、觀測時間三者結合起來,形成乙個經度資料,引入每顆計算
將觀測者的朝向引入每顆計算
將觀測者的仰角引入每顆計算
向螢幕投影
**如下:
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)
# 經緯度轉換為xyz的三維座標
x0= cos(star[
'long'])
* cos(star[
'lat'])
y0= sin(star[
'long'])
* cos(star[
'lat'])
z0= sin(star[
'lat'])
# 觀測地經度及日期時間的合併
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)
# 觀測者轉身
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>
0and z4>0)
star[
'x']
= x4* eyedistant/z4
star[
'y']
= y4* eyedistant/z4
star[
'z']
= z4
星星可見的條件是:在地平線之上(z2>0)並且在觀測者面前(z4>0),而可見的星星是否真正顯示在螢幕上的則取決於它是否在螢幕顯示範圍內。顯示**如下:
img= image.new(
'rgba',(
1280
,720),
(0,0
,120
,255))
# 深藍色天空
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(
)
這個問題比想象的複雜太多。如果想做到真正的精確,會涉及平太陽日、真太陽日、恆星日、歲差、經度與本地時間的差異,等等很多細節。
不過,好在這些誤差並不太大,如果你的目標不是科研,並且只考慮近代而不是遠古和未來,有些誤差即使忽略也沒有太大的影響。
這裡我用乙個雖然簡略,但足夠精確的乙個經驗公式來計算。輸入觀測地經度、觀測日期和時間,返回乙個所謂的絕對經度,以這個經度作為我們計算星空位置所使用的經度值。
**如下:
def
getabslong
(along, ayy, amm, add, ahh, amin)
:# 年的影響忽略
# 月日的影響,首先計算太陽赤經
# 春分點3月21日為經度0,一年平均365.25天,旋轉360度,用插值方法簡單計算
a= julianday(ayy, amm, add)
b= julianday(ayy,3,
21)v=0-
(a-b)
/365.25
*360
# 因為使用本地時間,基本可以忽略經度+時區的影響(互相抵消)
# 時分的影響,中午12點,正對太陽赤經,一天24小時,旋轉360度,用插值簡單計算
c= ahh*
60+amin
d=12*
60 v= v-
(c-d)/(
24*60)
*360
return v
星座連線用於輔助我們理解星座形狀。結構很簡單,就是指明一條線關聯哪兩個點。這裡不展開了,詳見**。
,,
,,,,
,,,,
,
python執行星空 用Python顯示真實的星空
用python顯示真實的星空 還是先上圖 本文講怎樣畫出真實的星空。預備知識,每顆星星包含4個資訊 天球經度long 天球緯度lat 亮度light 越小越亮 所屬星座const。想象所有的星星都鑲嵌在乙個天球上,它們的位置是固定不變的,所以叫做恆星。星星的座標用經緯度來表示,就如同地球上的位置用經...
用python畫梵谷星空 python畫畫梵谷
眾多的第三方庫 解釋執行,不需要編譯 跨平台,方便移植 兩個詞總結起來就是 簡單 方便。2 不務正業 的python更可怕的是,某些實用主義者將python的靈活性發揮到了極致。有的人想節省房租,用python爬出了全上海7萬多套 只為了挑選出自己喜歡的房子。有的人想畫畫,用python模仿出了梵谷...
Python 用 OpenCV 顯示文字 6
利用 opencv 自帶的puttext 函式繪製文字並顯示,其函式宣告如下 cv2.puttext img,text,org,fontface,fontscale,color thickness linetype bottomleftorigin bottomleftorigin 為 true,影...