ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python的真实感图形生成(含源码)

2021-05-16 18:01:41  阅读:395  来源: 互联网

标签:python xc yc zc 真实感图形 yp xp zp 源码


基于python生成真实感图形

简介

  本文是利用python生成一颗行星以及它周围的环带,它是由线、点构造而成的二维平面图形。

一、运行结果图

  源代码运行结果如下:
在这里插入图片描述
  去掉坐标轴结果如下:
在这里插入图片描述

二、python源码

  实现以上结果源码如下:

"""
  本代码绘制了小行星以及它周围的环带
"""
import numpy as np
import matplotlib.pyplot as plt
from math import sin, cos, radians, sqrt


def rotx(xc, yc, zc, xp, yp, zp, Rx):
    g[0] = xp + xc
    g[1] = yp * cos(Rx) - zp * sin(Rx) + yc
    g[2] = yp * sin(Rx) + zp * cos(Rx) + zc
    return g

def roty(xc, yc, zc, xp, yp, zp, Ry):
    g[0] = xp * cos(Ry) + zp * sin(Ry) + xc
    g[1] = yp + yc
    g[2] = -xp * sin(Ry) + zp * cos(Ry) + zc
    return g

def rotz(xc, yc, zc, xp, yp, zp, Rz):
    g[0] = xp * cos(Rz) - yp * sin(Rz) + xc
    g[1] = xp * sin(Rz) + yp * cos(Rz) + yc
    g[2] = zp + zc
    return g

plt.axis([0,150,100,0])
plt.axis('off')
plt.grid(False)

print('冲冲冲!!!!!')
#定义参数
g=[0]*3

xc=80 #圆心
yc=50
zc=0

rs=25 #球面半径

lx=-1 #光线单位矢量分量
ly=0
lz=0

IA=0 # 定义曲线
IB=.8
n=2

Rx=radians(-20)
Ry=radians(0)
Rz=radians(30)

# 添加背景色
for x in np.arange(0,150,1):
     for y in np.arange(0,100,1):
          plt.scatter(x,y,color = 'midnightblue')

#绘制球体
## 横向
phi1 = radians(-90)
phi2 = radians(90)
dhpi = radians(2)

alpha1 = radians(0)
alpha2 = radians(360)
dalpha = radians(2)

for alpha in np.arange(alpha1,alpha2+dalpha,dalpha):
    for phi in np.arange(phi1,phi2+dhpi,dhpi):
        xp = rs * cos(phi) * cos(alpha)
        yp = rs * sin(phi)
        zp = -rs * cos(phi) * sin(alpha)

        rotx(xc, yc, zc, xp, yp, zp, Rx)
        xp = g[0] - xc
        yp = g[1] - yc
        zp = g[2] - zc
        roty(xc, yc, zc, xp, yp, zp, Ry)
        xp = g[0] - xc
        yp = g[1] - yc
        zp = g[2] - zc
        rotz(xc, yc, zc, xp, yp, zp, Rz)
        xpg = g[0]
        ypg = g[1]
        zpg = g[2]
        a = xpg - xc
        b = ypg - yc
        c = zpg - zc

        qp = sqrt(a*a+b*b+c*c)
        nx = a/qp
        ny = b/qp
        nz = c/qp
        ndotl = nx * lx + ny * ly + nz * lz
        I = IA + (IB-IA)*((1+ndotl)/2)**n

        if phi == phi1:
            xpglast = xpg
            ypglast = ypg
        if nz < 0:
            plt.plot([xpglast,xpg],[ypglast,ypg],linewidth = 4,
                     color = ((1-I),.8*(1-I),.45*(1-I)))
            xpglast = xpg
            ypglast = ypg
## 纵向
for phi in np.arange(phi1,phi2+dhpi,dhpi):
    r = rs * cos(phi)
    for alpha in np.arange(alpha1, alpha2 + dalpha, dalpha):
        xp = r * cos(alpha)
        yp = rs * sin(phi)
        zp = -rs * cos(phi) * sin(alpha)

        rotx(xc, yc, zc, xp, yp, zp, Rx)
        xp = g[0] - xc
        yp = g[1] - yc
        zp = g[2] - zc
        roty(xc, yc, zc, xp, yp, zp, Ry)
        xp = g[0] - xc
        yp = g[1] - yc
        zp = g[2] - zc
        rotz(xc, yc, zc, xp, yp, zp, Rz)
        xpg = g[0]
        ypg = g[1]
        zpg = g[2]

        a = xpg - xc
        b = ypg - yc
        c = zpg - zc

        qp = sqrt(a*a+b*b+c*c)
        nx = a/qp
        ny = b/qp
        nz = c/qp
        ndotl = nx * lx + ny * ly + nz * lz
        textbfI = IA + (IB-IA)*((1+ndotl)/2)**n

        if alpha == alpha1:
            xpglast = xpg
            ypglast = ypg
        if nz < 0:
            plt.plot([xpglast,xpg],[ypglast,ypg],linewidth = 4,
                     color = ((1-I),.8*(1-I),.45*(1-I)))
            xpglast = xpg
            ypglast = ypg

#绘制外围环形带
alpha1=radians(-10)
alpha2=radians(370)
dalpha=radians(.5)

r1=rs*1.5
r2=rs*2.2
dr=rs*.02
deltar=(r2-r1)/7 #环形带宽

#旋转位于rα的环点p
for r in np.arange(r1,r2,dr):
    for alpha in np.arange(alpha1,alpha2,dalpha):
        xp=r*cos(alpha)
        yp=0
        zp=-r*sin(alpha)
        rotx(xc,yc,zc,xp,yp,zp,Rx)
        xp=g[0]-xc
        yp=g[1]-yc
        zp=g[2]-zc
        roty(xc,yc,zc,xp,yp,zp,Ry)
        xp=g[0]-xc
        yp=g[1]-yc
        zp=g[2]-zc
        rotz(xc,yc,zc,xp,yp,zp,Rz)
        xpg=g[0]
        ypg=g[1]
        zpg=g[2]


#选择环带颜色
        if r1 <= r < r1+1*deltar:
            clr=(.63,.54,.18)
        if r1+1*deltar <= r <= r1+2*deltar:
            clr=(.78,.7,.1)
        if r1+2*deltar <= r <= r1+3*deltar:
            clr=(.95,.85,.1)
        if r1+3*deltar <= r <= r1+4*deltar:
            clr=(.87,.8,.1)
        if r1+5*deltar <= r <= r1+7*deltar:
            clr=(.7,.6,.2)

#阴影
        magu=sqrt(lx*lx+ly*ly+lz*lz)
        ux=-lx/magu
        uy=-ly/magu
        uz=-lz/magu
        vx=xc-xpg
        vy=yc-ypg
        vz=zc-zpg
        Bx=uy*vz-uz*vy
        By=uz*vx-ux*vz
        Bz=ux*vy-uy*vx
        magB=sqrt(Bx*Bx+By*By+Bz*Bz)
        if magB < rs: #在阴影区域
            if vx*lx+vy*ly+vz*lz <= 0:
                clr=(.5,.5,.2)

        if r1+4*deltar <= r <= r1+5*deltar:
            clr='midnightblue'

#绘制线段
        if alpha == alpha1:
            xstart=xpg
            ystart=ypg
        if zpg <= zc:
            plt.plot([xstart,xpg],[ystart,ypg],linewidth=2,color=clr)

        if zpg >= zc:
            a=xpg-xc
            b=ypg-yc
            c=sqrt(a*a+b*b)
            if c > rs*1.075: #仅绘制环的可见部分
                plt.plot([xstart,xpg],[ystart,ypg],linewidth=2,color=clr)
            xstart=xpg
            ystart=ypg

plt.show()

三、实现思路

  本绘制总共分为三部分:首先是定义参数,其次是绘制中心的球体,最后是绘制外围环带。
  定义参数是通过建立数学模型,借了书中的示例,对数学感兴趣可参考《python图形编程2D和3D图像的创建》这本书。
  绘制球体和外围环带有遮挡和阴影,需要消隐之类的操作,这些在实现的过程中有一定难度。
  本图绘制是用线、点构成的,其中背景是用点来构成,而图形是采用线构成,前文效果展示时看不出来,但是将局部放大展示使可以很清楚的看到。这也让我更深刻的理解了“点动成线、线动成面”这句话。很棒!希望本文对学习中的您有帮助。
  局部展示图:点为背景,线为图像。
在这里插入图片描述

标签:python,xc,yc,zc,真实感图形,yp,xp,zp,源码
来源: https://blog.csdn.net/weixin_45873676/article/details/116886331

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有