手把手教你用Python画一个绝美土星环

2023-12-16 20:30

本文主要是介绍手把手教你用Python画一个绝美土星环,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


导读:本文带你了解 Python 图形工具能够做哪些事情。

作者:B. J. 科里特斯

来源:大数据DT(ID:hzdashuju)

土星的行星环非常出名。虽然木星、土星、天王星和海王星也有环,但土星环是我们太阳系中最大、最亮、最广为人知的行星环。

它由小到灰尘的颗粒,大到巨石的物体组成。这些物体的成分主要是冰,一般认为是彗星或较大的小行星与土星的一颗卫星相撞时产生的,两者都撞成了小碎块。在远古时代,土星就已为人所知,但直到1610年,伽利略才首次用望远镜对它进行观测。

这个行星以罗马农业之神土星Saturn命名为,也就是我们每个星期的第六天Saturday。

图1至图5中的图像是由本文文末的代码生成的。每张图都呈现不同的方向角,图标题中有相应的说明。

图标题中还列出了入射光线的单位矢量分量,例如lx=+0.707,ly=+0.707,lz=0 表示左上象限中的光源;lx=-1,ly=0,lz=0表示来自右侧的光源。在图像中请注意行星在环上投射的阴影,尤其是在图5中能够看到行星轮廓的曲率。

▲图1 包含土星环和阴影的土星1:Rx=-20°, Ry=0, Rz=-10°, lx=1, ly=0, lz=0

▲图2 包含土星环和阴影的土星2:Rx=-8°, Ry=0, Rz=-30°, lx=0.707, ly=.707, lz=0

▲图3 包含土星环和阴影的土星3:Rx=20°, Ry=0, Rz=25°, lx=0.707, ly=0.707, lz=0

▲图4 包含土星环和阴影的土星4:Rx=-10°, Ry=0, Rz=25°, lx=0.707, ly=-0.707, lz=0

▲图5 包含土星环和阴影的土星5:Rx=20°, Ry=0, Rz=30°, lx=-1, ly=0, lz=0

为了进行比较,我们再看一张土星的摄像图:

©NASA/JPL-Caltech/Space Science Institute/G. Ugarkovic (ISS), NASA/JPL-Caltech/University of Arizona/CNRS/LPG-Nantes (VIMS)

你可以在下面网址找到更多土星的摄像图:

https://www.jpl.nasa.gov/spaceimages/?search=saturn&category=#submit

图6所示为构建土星环所用的数学模型。这里介绍一种实现球体着色的算法。首先创建一个直立球体,也就是说,经度是垂直的,纬度是水平的(即平行于XZ平面),然后从初始方向开始,围绕x,y和z轴对球体进行旋转。

▲图6 土星环模型:行星俯视图和从XZ平面上Rx=0, Ry=0, Rz=0向下看环

我们对土星环也进行同样的操作。我们可以创建平行于XZ平面的水平环,然后将它和土星一起旋转相同的角度。土星环所处的平面穿过土星的球心,因此土星和环具有相同的旋转中心。

土星环绘制为一系列相邻的同心圆,每个同心圆由短线段组成。参考图6和文末代码,程序第42和43行设置了土星环的内半径和外半径,第44行设置同心圆的间距。土星环被分成七个同心环形带(图6中未画出)且具有不同的颜色,第45行的deltar是它们的宽度。

构成同心圆的每个线段都单独绘制。第48行从r1向r2进行绘制,通过径向循环绘制圆弧段。第49行是绕圆周方向绘制的循环。第50-61行执行旋转操作产生第62和63行中的全局绘图坐标xpg和ypg,旋转函数与先前程序中的相同。

接下来在第66-75行中设置线段的颜色。土星环是由不同颜色的条带构成的,这和NASA观测图像中看到的物理组成结果一致。从r = r1到r1 + deltar的第一个条带具有颜色clr=(.63,.54,.18),剩余的条带也是如此。

第五个条带省略掉了,因为它是空的,背景颜色能显示出来。第六个条带的宽度是其他条带的两倍,并且为第七个条带提供了颜色。

对于给定的光方向,从大多数角度上,行星体本身都会在环上投下阴影。参考图7,我们的目标是确定点p到底位于行星阴影区域内部还是外部。

球状的行星将产生圆形的阴影,阴影的直径与行星的尺寸相等,或者更准确地说,是球体的“大圆”。它是用通过圆心的平面切割球体而得到的最大圆,就像把橙子切成两半,你看到的是一个橙子的最大圆。

在图7中,这种阴影可能是由相同大小的圆盘投影产生的,也可能是由球状行星投影产生的,两种情况下,阴影的大小都是一样的。在土星的侧面图中,大圆显示为是一条通过平面中心的加粗线。

从图7的几何图形中可以看出,如果p位于|B| > rs的位置,则它位于阴影区之外,其中rs是土星的半径;如果|B| < rs,则p位于在阴影区之中。在绘制条带的时候,如果我们确定了p的位置在阴影区中,我们就把这个点涂成灰色,如果它在阴影区之外,我们就用第66-75行设置的条带颜色给它着色。

▲图7 阴影模型

我们的目标是求出给定位置p时的|B|值,由图7可看出:

|B|=|V|sin(φ)

并且我们知道:

V×û=|V||û|sin(φ)

其中û=-î 。将上述方程与|û|=1合并得:

B=V×û

|B|=|V×û|

在代码第78行中确定了入射光矢量î 的长度为1,但如果在第23-25行中输入的分量不计算为1(即),则入射光矢量可能不等于1。有必要的话,需要在第79-81行进行重构。第82-84行建立矢量V的分量。第85-87行计算B的分量。第88行给出其幅度magB = |B|。

第89行确定p是否位于阴影区内,如果是,则执行第90行V与î的点积。这是用来确定p是否位于行星朝向光源的一侧,在这种情况下,它与行星的暗侧相对,而不在阴影区。因为在第78-89行的阴影算法中并未区分p的位置,所以此处必须进行明确。如果p确实位于阴影区域内的暗侧,则在第91行中将p设置为中等灰色。

相信你一定注意到,图6的土星环上有一个暗色条带,这是因为土星环在该位置上是空的:那里没有固体颗粒物,不能反射阳光。因此我们透过条带看到了背景颜色'midnightblue'。但这会产生一个问题,即阴影颜色的绘制会覆盖该空白处的背景颜色,因此在第93和94行将其重置为'midnightblue'。

既然条带的颜色都建立好了,我们就可以通过一个个短线段来绘制土星环了。第97-100行计算第一个线段的起始位置。参考图6,第100-101行确定该线段与土星的遮挡关系,线段在前就会被绘制。

103-108行确定线段是否在土星后面,位于后面就不会被绘制。这种遮挡关系是通过计算点的全局坐标与土星中心之间的距离c来完成的。

第107行的意思是,如果c大于球体半径的1.075倍,则绘制该段。因子1.075的作用是防止线段与球体的表面重合,这是有必要的,不然小于球体半径的可见区段将不会被绘制。

本文代码生成的图像有两点需要注意:首先是颜色。美国宇航局的摄影图像呈现的是一种几乎没有颜色灰色,但是许多土星观察者都将它描述为金黄色,因此我们选择了金色。

所有摄影师都知道,在摄影图像中呈现物体的真实颜色是十分困难的,颜色取决于入射光和物体本身的颜色,或许最好的方法是依靠肉眼观察。

如果你不赞同本文代码所生成的图像中的颜色,可以通过更改程序中clr的定义来修改它们。需要注意的第二点,是图5中土星表面阴影的曲率,它表示着色算法是否按预期工作。

在程序的使用上,你可以自行更改第24-26行中的入射光的方向和第32-34行中的旋转角度。

本文篇幅有限,更多更详细的讲解请参阅《Python图形编程:2D和3D图像的创建》一书。

  • 土星代码

运行代码也需要一段时间,请耐心等待。

  1"""2SATURN3"""45import numpy as np6import matplotlib.pyplot as plt7from math import sin, cos, radians, sqrt89plt.axis([0,150,100,0])10plt.axis('off')11plt.grid(False)1213print('running')14#—————————————————parameters15g=[0]*31617xc=80 #———sphere center18yc=5019zc=02021rs=25 #———sphere radius2223lx=-1 #———light ray unit vector components24ly=025lz=02627IA=028IB=.829+n=23031Rx=radians(-20)32Ry=radians(0)33Rz=radians(30)3435#————————same as SHADESPHERE—————–3637#———————————————————rings38alpha1=radians(-10)39alpha2=radians(370)40dalpha=radians(.5)4142r1=rs*1.543r2=rs*2.244dr=rs*.0245deltar=(r2-r1)/7 #———ring band width4647#—————————————rotate ring point p which is at r, alpha48for r in np.arange(r1,r2,dr):49    for alpha in np.arange(alpha1,alpha2,dalpha):50        xp=r*cos(alpha)51        yp=052        zp=-r*sin(alpha)53        rotx(xc,yc,zc,xp,yp,zp,Rx)54        xp=g[0]-xc55        yp=g[1]-yc56        zp=g[2]-zc57        roty(xc,yc,zc,xp,yp,zp,Ry)58        xp=g[0]-xc59        yp=g[1]-yc60        zp=g[2]-zc61        rotz(xc,yc,zc,xp,yp,zp,Rz)62        xpg=g[0]63        ypg=g[1]6465#—————————————————select ring band color66    if r1 <= r < r1+1*deltar:67        clr=(.63,.54,.18)68    if r1+1*deltar <= r <= r1+2*deltar:69        clr=(.78,.7,.1)70    if r1+2*deltar <= r <= r1+3*deltar:71        clr=(.95,.85,.1)72    if r1+3*deltar <= r <= r1+4*deltar:73        clr=(.87,.8,.1)74    if r1+5*deltar <= r <= r1+7*deltar:75        clr=(.7,.6,.2)7677#———————————————————————shadow78    magu=sqrt(lx*lx+ly*ly+lz*lz)79    ux=-lx/magu80    uy=-ly/magu81    uz=-lz/magu82    vx=xc-xpg83    vy=yc-ypg84    vz=zc-zpg85    Bx=uy*vz-uz*vy86    By=uz*vx-ux*vz87    Bz=ux*vy-uy*vx88    magB=sqrt(Bx*Bx+By*By+Bz*Bz)89    if magB < rs: #—————————if in the shadow region90        if vx*lx+vy*ly+vz*lz <= 0: #———if v points toward light source91            clr=(.5,.5,.2) #———shadow color9293    if r1+4*deltar <= r <= r1+5*deltar: #———overplot empty band94        clr='midnightblue' #———with background color9596#——————————————————–plot line segment97    if alpha == alpha1:98        xstart=xpg99        ystart=ypg
100    if zpg <= zc: #–front (z axis points into the screen)
101        plt.plot([xstart,xpg],[ystart,ypg],linewidth=2,color=clr)
102
103    if zpg >= zc: #–back
104        a=xpg-xc
105        b=ypg-yc
106        c=sqrt(a*a+b*b)
107        if c > rs*1.075: #——plot only the visible portion of rings
108            plt.plot([xstart,xpg],[ystart,ypg],linewidth=2,color=clr)
109        xstart=xpg
110        ystart=ypg
111
112plt.show()

关于作者:B. J. 科里特斯,博士,一直从事计算机工程和科学应用。他是一名教育家、顾问,著有十多本关于几何建模、计算机图形学、人工智能、物理过程模拟、结构分析、计算机在科学和工程中的应用的书籍。

本文摘编自《Python图形编程:2D和3D图像的创建》,经出版方授权发布。

延伸阅读《Python图形编程》

点击上图了解及购买

转载请联系微信:DoctorData

推荐语:一本书教你学会Python图形图像编程及可视化。本书使用Python的内置特征创建用于数据可视化和技术说明的创新图形。从构建绘图空间和生成2维和3维对象的基本Python函数开始,你将学习如何构造更复杂的对象、转换和旋转、删除隐藏线、引入阴影以添加真实感以及将图像投影到任何数据集上。

划重点????

干货直达????

  • 大厂和初创公司都在用!Redis好在哪?终于有人讲明白了

  • 5种不会被机器智能替代的能力

  • 世界一流大学的计算机专业,在用哪些书当教材?

  • 什么是机器阅读理解?跟自然语言处理有什么关系?

更多精彩????

在公众号对话框输入以下关键词

查看更多优质内容!

PPT | 读书 | 书单 | 硬核 | 干货 

大数据 | 揭秘 | Python | 可视化

AI | 人工智能 | 5G | 中台

机器学习 | 深度学习 | 神经网络

合伙人 1024 | 大神 | 数学

据统计,99%的大咖都完成了这个神操作

????

这篇关于手把手教你用Python画一个绝美土星环的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/501784

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',

Python QT实现A-star寻路算法

目录 1、界面使用方法 2、注意事项 3、补充说明 用Qt5搭建一个图形化测试寻路算法的测试环境。 1、界面使用方法 设定起点: 鼠标左键双击,设定红色的起点。左键双击设定起点,用红色标记。 设定终点: 鼠标右键双击,设定蓝色的终点。右键双击设定终点,用蓝色标记。 设置障碍点: 鼠标左键或者右键按着不放,拖动可以设置黑色的障碍点。按住左键或右键并拖动,设置一系列黑色障碍点

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

【Python报错已解决】AttributeError: ‘list‘ object has no attribute ‘text‘

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一:检查属性名2.2 步骤二:访问列表元素的属性 三、其他解决方法四、总结 前言 在Python编程中,属性错误(At