如何用Python画一个绝美土星环

技术如何用Python画一个绝美土星环本篇文章为大家展示了如何用Python画一个绝美土星环,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。土星的行星环非常出名。虽然木星、土星、天

这篇文章向你展示了如何用Python绘制一个美丽的土星环。内容简洁易懂,一定会让你眼前一亮。希望通过这篇文章的详细介绍,你能有所收获。

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

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

这颗行星以罗马农业之神土星命名,土星是我们一周的第六天。

图1到图5中的图像是由本文末尾的代码生成的。每张图片呈现不同的方向角,图片标题中给出了相应的描述。

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

如何用Python画一个绝美土星环

图1土星1:Rx=-20度带土星环和阴影;Ry=0,Rz=-10 deg;lx=1,ly=0,lz=0

如何用Python画一个绝美土星环

图2土星2带土星环和阴影:Rx=-8;Ry=0,Rz=-30 deg;lx=0.707,ly=0.707,lz=0

如何用Python画一个绝美土星环

图3土星3带土星环和阴影:Rx=20度;Ry=0,Rz=25度;lx=0.707,ly=0.707,lz=0

如何用Python画一个绝美土星环

图4土星4带土星环和阴影:Rx=-10度;Ry=0,Rz=25度;lx=0.707,ly=-0.707,lz=0

如何用Python画一个绝美土星环

图5土星5包括土星环和阴影:Rx=20度;Ry=0,Rz=30度;lx=-1,ly=0,lz=0

作为对比,你可以在以下网站找到土星的照片:

https://www.jpl.nasa.gov/spaceimages/?搜索=saturncategory=#提交

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

如何用Python画一个绝美土星环

图6土星环模型:从XZ平面看行星和环的俯视图,Rx=0,Ry=0,Rz=0 0,Rz=0。

我们对土星环也是如此。我们可以创建一个平行于XZ平面的水平环,然后将其与土星以相同的角度旋转。土星环的平面穿过土星球体的中心,所以土星和环有相同的旋转中心。

土星环被绘制成一系列相邻的同心圆,每个同心圆都由小段组成。参考图6和文章末尾的代码,土星环的内半径和外半径设置在第42行和第43行,同心圆之间的距离设置在第44行。土星环被分成七个不同颜色的同心环形带(图6中未显示),第45行的deltar是它们的宽度。

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

接下来,设置第66-75行线段的颜色。土星环由不同颜色的带组成,这与美国宇航局观测图像中看到的物理组成结果一致。R=r1至r1。

 deltar的第一个条带具有颜色clr=(.63,.54,.18),剩余的条带也是如此。

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

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

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

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

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

如何用Python画一个绝美土星环

▲图7 阴影模型

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

|B|=|V|sin(&phi;)

并且我们知道:

V&times;&ucirc;=|V||&ucirc;|sin(&phi;)

其中&ucirc;=-&icirc; 。将上述方程与|&ucirc;|=1合并得:

B=V&times;&ucirc;

|B|=|V&times;&ucirc;|

在代码第78行中确定了入射光矢量&icirc; 的长度为1,但如果在第23-25行中输入的分量不计算为1,即

如何用Python画一个绝美土星环

则入射光矢量可能不等于1。有必要的话,需要在第79-81行进行重构。第82-84行建立矢量V的分量。第85-87行计算B的分量。第88行给出其幅度magB  = |B|。

第89行确定p是否位于阴影区内,如果是,则执行第90行V与&icirc;的点积。这是用来确定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行中的旋转角度。

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

1"""   2SATURN   3"""   4   5import numpy as np   6import matplotlib.pyplot as plt   7from math import sin, cos, radians, sqrt   8   9plt.axis([0,150,100,0])  10plt.axis('off')  11plt.grid(False)  12  13print('running')  14#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;parameters  15g=[0]*3  16  17xc=80 #&mdash;&mdash;&mdash;sphere center  18yc=50  19zc=0  20  21rs=25 #&mdash;&mdash;&mdash;sphere radius  22  23lx=-1 #&mdash;&mdash;&mdash;light ray unit vector components  24ly=0  25lz=0  26  27IA=0  28IB=.8  29+n=2  30  31Rx=radians(-20)  32Ry=radians(0)  33Rz=radians(30)  34  35#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;same as SHADESPHERE&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;  36  37#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;rings  38alpha1=radians(-10)  39alpha2=radians(370)  40dalpha=radians(.5)  41  42r1=rs*1.5  43r2=rs*2.2  44dr=rs*.02  45deltar=(r2-r1)/7 #&mdash;&mdash;&mdash;ring band width  46  47#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;rotate ring point p which is at r, alpha  48for r in np.arange(r1,r2,dr):  49    for alpha in np.arange(alpha1,alpha2,dalpha):  50        xp=r*cos(alpha)  51        yp=0  52        zp=-r*sin(alpha)  53        rotx(xc,yc,zc,xp,yp,zp,Rx)  54        xp=g[0]-xc  55        yp=g[1]-yc  56        zp=g[2]-zc  57        roty(xc,yc,zc,xp,yp,zp,Ry)  58        xp=g[0]-xc  59        yp=g[1]-yc  60        zp=g[2]-zc  61        rotz(xc,yc,zc,xp,yp,zp,Rz)  62        xpg=g[0]  63        ypg=g[1]  64  65#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;select ring band color  66    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)  76  77#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;shadow  78    magu=sqrt(lx*lx+ly*ly+lz*lz)  79    ux=-lx/magu  80    uy=-ly/magu  81    uz=-lz/magu  82    vx=xc-xpg  83    vy=yc-ypg  84    vz=zc-zpg  85    Bx=uy*vz-uz*vy  86    By=uz*vx-ux*vz  87    Bz=ux*vy-uy*vx  88    magB=sqrt(Bx*Bx+By*By+Bz*Bz)  89    if magB < rs: #&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;if in the shadow region  90        if vx*lx+vy*ly+vz*lz <= 0: #&mdash;&mdash;&mdash;if v points toward light source  91            clr=(.5,.5,.2) #&mdash;&mdash;&mdash;shadow color  92  93    if r1+4*deltar <= r <= r1+5*deltar: #&mdash;&mdash;&mdash;overplot empty band  94        clr='midnightblue' #&mdash;&mdash;&mdash;with background color  95  96#&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;plot line segment  97    if alpha == alpha1:  98        xstart=xpg  99        ystart=ypg 100    if zpg <= zc: #&ndash;front (z axis points into the screen) 101        plt.plot([xstart,xpg],[ystart,ypg],linewidth=2,color=clr) 102 103    if zpg >= zc: #&ndash;back 104        a=xpg-xc 105        b=ypg-yc 106        c=sqrt(a*a+b*b) 107        if c > rs*1.075: #&mdash;&mdash;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()

上述内容就是如何用Python画一个绝美土星环,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/54364.html

(0)

相关推荐

  • 用python做未来的预测(数据预测怎么用python做)

    技术如何在R中使用开源大规模预测工具Prophet这期内容当中小编将会给大家带来有关如何在R中使用开源大规模预测工具Prophet,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Prop

    攻略 2021年12月20日
  • Form表单使用、ajax解决表单提交后页面跳转数据丢失的问题缺点

    技术Form表单使用、ajax解决表单提交后页面跳转数据丢失的问题缺点 Form表单使用、ajax解决表单提交后页面跳转数据丢失的问题缺点一、Form表单基本使用
    表单概念:在网页中主要负责 数据采集功

    礼包 2021年10月19日
  • JDK源码阅读(7):ConcurrentHashMap类阅读笔记

    技术JDK源码阅读(7):ConcurrentHashMap类阅读笔记 JDK源码阅读(7):ConcurrentHashMap类阅读笔记JDK源码阅读(7):ConcurrentHashMap类阅读笔

    礼包 2021年11月25日
  • 如何用OAuth 2.0实现权限认证mybatis连接mysql数据库

    技术如何用OAuth 2.0实现权限认证mybatis连接mysql数据库本篇内容介绍了“如何用OAuth 2.0实现权限认证mybatis连接mysql数据库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困

    攻略 2021年12月4日
  • Zookeeper的基础知识是什么

    技术Zookeeper的基础知识是什么本篇文章为大家展示了Zookeeper的基础知识是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。简介Apache ZooKeeper是一

    攻略 2021年11月12日
  • LeetCode538 把二叉搜索树转为累加树

    技术LeetCode538 把二叉搜索树转为累加树 LeetCode538 把二叉搜索树转为累加树题目
    给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum T

    礼包 2021年12月13日