用Python显示真实的星空

还是先上图

本文讲怎样画出真实的星空。

预备知识如果想显示真实的星空,首先你得有真实恒星的位置坐标和亮度标记。它的基本格式如下:

{'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个信息:天球经度long、天球纬度lat、亮度light(越小越亮)、所属星座const。

想象所有的星星都镶嵌在一个天球上,它们的位置是固定不变的,所以叫做恒星。

星星的坐标用经纬度来表示,就如同地球上的位置用经纬度来表示。当地球旋转时,我们看到的是天球的旋转。

我们所熟悉的北极星,就在非常靠近天球北极的位置上。

在天球旋转的过程中,它的位置几乎不动。也就是说北极星的位置几乎在任何时候都保持在天空中固定的位置上。之所以能够用北极星来指示方向,也就是这个原理。

另外,星空是球形的,想把它显示在屏幕上,又涉及几组基本参数的设置:

观测地的经纬度

观测的日期和时间

观测者的观测角度和屏幕大小

这几组参数中,关系是这样的:观测地的维度是第一位的,观测地确定后,所能看到的星空就是确定的(天球倾角),只有在赤道上能够看到所有的星星,在其它维度都会有一些星星看不到。

最极端的情况下是在两极地区,永远只能看到半个天球(即一半数量的星星)。

观测地的经度、观测日期和观测时间这三者其实是等价的,因为地球的公转和自转对于遥远的星空来说,可以认为没有差别。

当观测点和观测日期时间都确定后,理论可以认为所能看到的星空大约有全天中半数的星星。但能够显示在屏幕上的星星,则取决于你向哪里观看以及屏幕有多大。

如果能够理解上面这些基本知识,请继续往下看。

星空计算

计算经过这样几个步骤:

1、为了便于计算,首先将每颗星星的经纬度转换为xyz的三维坐标。在这种转换过程中,我们看到的是正立的天球,北极点向上,南极点在下。

2、将观测地的纬度引入每颗计算

3、将观测地经度、观测日期、观测时间三者结合起来,形成一个经度数据,引入每颗计算

4、将观测者的朝向引入每颗计算

5、将观测者的仰角引入每颗计算

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)

# 经纬度转换为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> 0 and 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

星座连线是怎么来的

星座连线用于辅助我们理解星座形状。结构很简单,就是指明一条线关联哪两个点。这里不展开了,详见代码。{'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},

更多Python知识,请关注Python视频教程!!

python星空代码_Python中的唯美星空代码详解!相关推荐

  1. python支持向量机回归_Python中支持向量机SVM的使用方法详解

    除了在Matlab中使用PRTools工具箱中的svm算法,Python中一样可以使用支持向量机做分类.因为Python中的sklearn库也集成了SVM算法,本文的运行环境是Pycharm. 一.导 ...

  2. Python 3.7.1 中 namedtuple 具名元组基本用法详解

    Python 3.7.1 中 namedtuple 具名元组基本用法详解 转载请注明出处:https://blog.csdn.net/jpch89/article/details/84645251 文 ...

  3. python post json参数,Python requests.post方法中data与json参数区别详解

    在通过requests.post()进行POST请求时,传入报文的参数有两个,一个是data,一个是json. data与json既可以是str类型,也可以是dict类型. 区别: 1.不管json是 ...

  4. python scatter参数详解_Python中scatter函数参数及用法详解

    最近开始学习Python编程,遇到scatter函数,感觉里面的参数不知道什么意思于是查资料,最后总结如下: 1.scatter函数原型 2.其中散点的形状参数marker如下: 3.其中颜色参数c如 ...

  5. python scatter参数详解_Python 中 scatter 函数参数及用法详解

    Python 中 scatter 函数参数及用法详解 Python 中 scatter 函数参数及用法详解 这里有新鲜出炉的 Python 教程, 程序狗速度看过来! Python 编程语言 Pyth ...

  6. python中列表的sort方法_python中列表的sort方法使用详解

    内容简介:python中列表的sort方法使用详解 一.基本形式 列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不可修改的. 排序,数字.字符 ...

  7. python format函数实例_python中强大的format函数实例详解

    python中format函数用于字符串的格式化 自python2.6开始,新增了一种格式化字符串的函数str.format(),此函数可以快速处理各种字符串. 语法 它通过{}和:来代替%. 请看下 ...

  8. python中mat函数_Python中flatten( )函数及函数用法详解

    flatten()函数用法 flatten是numpy.ndarray.flatten的一个函数,即返回一个一维数组. flatten只能适用于numpy对象,即array或者mat,普通的list列 ...

  9. python中seek(10、1)_Python中index()和seek()的用法(详解)

    1.index() 一般用处是在序列中检索参数并返回第一次出现的索引,没找到就会报错,比如: >>> t=tuple('Allen') >>> t ('A', 'l ...

  10. python中update是啥意思_python中update的基本使用方法详解

    前言 Python 字典 update()方法用于更新字典中的键/值对,可以修改存在的键对应的值,也可以添加新的键/值对到字典中. 语法格式 d.update(e) 参数说明 将e中键-值对添加到字典 ...

最新文章

  1. 完全理解 Python 迭代对象、迭代器、生成器(转)
  2. Http协议 详解(转载)
  3. vuecli项目文件命名_vue.js学习笔记(一)——vue-cli项目的目录结构
  4. fastreport(A)
  5. poj 1160(Post Office)
  6. python | np.eye()函数
  7. NEFU394 素数价值
  8. annotations' in project ':test'. Resolved versions for app (26.1.0) and test app (27.1.1) differ
  9. char java 回文_LeetCode刷题笔记(Java)---第1-18题
  10. leetcode - 486. 预测赢家
  11. 一个C++的ElasticSearch Client
  12. 转:开源数据库中间件MyCat实现数据库读写分离、分表分库指南
  13. 百度编辑器ueditor字体添加
  14. 设计模式(二)—— 策略模式(其实就是面向接口编程的应用场景!)
  15. C# 获取适配器网络连接IP地址,子网掩码,DNS,数据包等信息
  16. vue实现监控流-rtsp转flv
  17. 数据存储策略——lsm-tree
  18. 抽象类,抽象方法,继承调用实现
  19. PostgreSQL得出两个timestamp的秒数差值
  20. 手把手教你,把3D模型从stl格式导出iges格式的方法

热门文章

  1. 【Java类的封装性】封装的日期类。Person类,使用对象作为成员变量并实现深拷贝。(利用了类的封装性)
  2. iMeta | 北大陈峰/陈智滨等发表口腔微生物组研究中各部位取样的实验方法(Protocol)...
  3. win10局域网访问其他计算机名,教你win10两台电脑怎么连接局域网
  4. 系统启动过程(基于三星s5p6818 uboot)
  5. MIPI-DSI 三种 Video Mode 理解
  6. 20155313 杨瀚 《网络对抗技术》实验七 网络欺诈防范
  7. 提供免费的Java OA系统 解决方案
  8. 二分查找边界问题总结
  9. 企业对NAS私有云存储有什么样的需求,NAS网络存储又有哪些优势与功能呢?
  10. 几款强力压缩打包软件