Python+OpenGL制作一个元宵花灯

目录
  • 1.准备
  • 2.快速体验
  • 3.模型动画
  • 4.子图布局
  • 5.颜色映射
  • 6.走马灯

又是一年元宵节,作为程序员的你,打算怎么过呢?如果昨天情人节的红包发得手软又心疼,不妨静下心来,了解一下三维数据可视化,顺便做一盏花灯送给女朋友,也许比红包更能讨她欢心呢。

1.准备

三维数据快速可视化工具,我喜欢用WxGL。这是一个基于PyOpenGL的三维数据可视化库,提供类似Matplotlib风格的3D绘图函数。如果熟悉NumPy和Matplotlib的话,只需要几分钟时间就可以学会使用WxGL的交互式绘图。

WxGL模块使用pip命令安装。

pip install wxgl

安装完成后,可以在Python IDLE中查看版本信息。

>>> import wxgl
>>> wxgl.version
'0.8.5'

2.快速体验

元宵、花灯和月亮,是元宵节的三大主题元素。我们就以一个文艺范儿的月亮开启WxGL的体验之旅吧。

import wxgl.wxplot as plt

plt.title('江天一色无纤尘,皎皎空中孤月轮')
plt.uvsphere((0,0,0), 1, lon=(0,360), lat=(90,-90), texture='res/moon.jpg', light=None)
plt.text('众里寻他千百度,', pos=(1.2,-0.3,0), size=128)
plt.text('蓦然回首,', pos=(1.2,-0.5,0), size=128)
plt.text('那人却在灯火阑珊处。', pos=(1.2,-0.7,0), size=128)
plt.show()

这几行代码,使用uvsphere球面函数绘制了一个中心点在三维坐标系原点、半径为1的月亮。忽略模块名的话,这些代码和Matplotlib的风格几乎是完全一致的,甚至函数名都是相同的。

运行show函数会弹出一个窗口,显示绘制的模型。窗口底部提供了一组工具按钮,可以设置系统参数、切换画布风格、显示或隐藏坐标网格、播放动画、保存或录制屏幕等。和Matplotlib一样,该窗口将阻塞程序运行,直至关闭该窗口。

3.模型动画

通过transform参数传递一个以时间长度为参数的函数给uvsphere球面函数,就可以让上面的月亮转动起来。

import wxgl.wxplot as plt

plt.title('江天一色无纤尘,皎皎空中孤月轮')
plt.uvsphere((0,0,0), 1, 
    lon = (0,360), 
    lat = (90,-90), 
    texture = 'res/moon.jpg', 
    transform = lambda duration : ((0, 1, 0, (0.02*duration)%360),),
    light = None # 关闭灯光效果,环境光会自动增强
)
plt.text('众里寻他千百度,', pos=(1.2,-0.3,0), size=128)
plt.text('蓦然回首,', pos=(1.2,-0.5,0), size=128)
plt.text('那人却在灯火阑珊处。', pos=(1.2,-0.7,0), size=128)
plt.show()

代码中lambda函数——当然也可以是普通的函数,其参数duration是以毫秒为单位的时间长度。该函数返回月球围绕一个向量(此处为(0,1,0),即y轴)旋转的角度。点击播放按钮,月球即开始以20°/s的速度旋转。

对了,差点儿忘记提供月球的纹理图片了。点击此处可下载不带水印的月球纹理图片。

4.子图布局

在一张画布上可以任意放置多个子图。下面的代码演示了子图布局函数subplot的经典用法。实际上,这个函数比Matplotlib的同名函数更灵活和便捷。

import wxgl.wxplot as plt

plt.subplot(121)
plt.title('经纬度网格生成球体')
plt.uvsphere((0,0,0), 1, color='coral', fill=False, slices=15)
plt.subplot(122)
plt.title('正八面体迭代细分生成球体')
plt.isosphere((0,0,0), 1, color='cyan', fill=False, iterations=2)
plt.show()

在画布上创建两个子图,使用两种不同的方式绘制球,并设置填充模式。由于使用相同的视点系统,两个子图上的模型可以保持同步。

5.颜色映射

对于数据快速可视化工具来说,颜色映射是必不可少的。下面的代码演示了ColorBar的用法。代码中的jet、Paired、rainbow等颜色映射表继承自Matplotlib库。

import numpy as np
import wxgl.wxplot as plt

vs = np.random.random((300, 3))*2-1
color = np.random.random(300)
size = np.random.randint(3, 15, size=300)
plt.scatter(vs, color, 'jet', size=size)
plt.colorbar('jet', [-1, 1], loc='right')
plt.colorbar('Paired', [-5, 5], loc='bottom', subject='温度')
plt.colorbar('rainbow', [0, 77], loc='bottom', subject='速度')
plt.title('scatter函数和colorbar函数示例')
plt.show()

WxGL允许在一张图上使用两个垂直风格的ColorBar和三个水平风格的ColorBar。

6.走马灯

去年元宵节我写过一篇绘制3D花灯的博客,用的工具也是WxGL,当时的版本还是0.6.4。牛去虎来,整整一年过去了,WxGL终于艰难地升级到了0.8.5,那篇博客中的代码也必须要升级了。

import numpy as np
import wxgl.wxplot as plt

r = 1 # 花灯半径为1
tf_bull = lambda duration : ((0, 1, 0, (0.02*duration)%360),) # 模型动画函数

# 以下生成花灯筒状龙骨
theta = np.linspace(0, 2*np.pi, 361) # 在0°~360°范围内间隔1°均匀生成361个角度
xs = r * np.tile(np.cos(theta), (150,1)) # 半径为r的圆周上361点的x坐标,重复150次,得到150行361列的二维数组
zs = r * np.tile(-np.sin(theta), (150,1)) # 半径为r的圆周上361点的z坐标,重复150次,得到150行361列的二维数组
ys = np.repeat(np.linspace(2.7, 0, 150), 361).reshape(150,361) # 0~2.7范围内均匀生成150个点,每个重复361,得到150行361列的二维数组

# 以下生成花灯叶轮
theta = np.linspace(0, 2*np.pi, 18, endpoint=False)
x, z = r * np.cos(theta), r * np.sin(theta)
y = np.ones(18) * 2.5
x[2::3] = x[1::3]
x[1::3] = 0
z[2::3] = z[1::3]
z[1::3] = 0
vs = np.stack((x,y,z), axis=1)

# 公牛动画函数:顺时针旋转,20°/s,向左平移1.2
tf_bull = lambda duration : ((0, 1, 0, (-0.02*duration)%360), (-1.2,0,0)) 

# 老虎动画函数:逆时针旋转,20°/s,向右平移1.2
tf_tiger = lambda duration : ((0, 1, 0, (0.02*duration)%360), (1.2,0,0)) 

plt.figure(elev=20) # 设置相机高度角为20°

# 公牛花灯
plt.mesh(xs, ys, zs, texture='res/bull.jpg', transform=tf_bull, light=None) # 花灯筒
plt.surface(vs, color=(0.75,0.2,0,0.8), transform=tf_bull) # 花灯叶轮
plt.uvsphere((0,0.8,0), 0.4, color='#FFFFFF', transform=((-1.2,0,0),), light=None) # 灯
plt.line([[0,1.2,0],[0,3.5,0]], color='red', width=3.0, transform=((-1.2,0,0),), inside=False) # 线

# 老虎花灯
plt.mesh(xs, ys, zs, texture='res/tiger.jpg', transform=tf_tiger, light=None) # 花灯筒
plt.surface(vs, color=(0.75,0.2,0,0.8), transform=tf_tiger) # 花灯叶轮
plt.uvsphere((0,0.8,0), 0.4, color='#FFFFFF', transform=((1.2,0,0),), light=None) # 灯
plt.line([[0,1.2,0],[0,3.5,0]], color='red', width=3.0, transform=((1.2,0,0),), inside=False) # 线

plt.show()

两只花灯使用相同的尺寸,画在同一个位置。花灯筒和叶轮的模型动画函数除了旋转还分别向左右移动了1.2个长度单位,而灯和线则只移动不旋转。最终效果如下图所示。

代码中用的公牛和老虎的花灯纹理,请点击下载:公牛、老虎。

到此这篇关于Python+OpenGL制作一个元宵花灯的文章就介绍到这了,更多相关Python OpenGL元宵花灯内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 通过Python OpenGL的point sprite技术绘制雪花

    看冬奥才知道,阿勒泰不但是中国的“雪都”,还是“人类滑雪起源地”.这个说法是否成立,姑且不论,阿勒泰的雪的确很漂亮.冬奥会有一个宣传片,就是借用一朵阿勒泰雪花的视角来讲述冬奥会的故事,既有历史的厚重,又有艺术的浪漫,极具视觉冲击感. 那么问题来了:如何用OpenGL绘制雪花呢?通常,点精灵(point sprite)技术被用于描述大量粒子在屏幕上的运动,自然也可以用于绘制雪花.点精灵可以理解为贴了纹理图片的点——仅用一个vertex就可以把一个2D纹理图片绘制到屏幕的任何位置. 在OpenGL中

  • 使用Python制作一盏 3D 花灯喜迎元宵佳节

    说起元宵节,各位有没有觉得这是咱们中国人最浪漫的节日呢?国人向来拘谨古板,一年到头都是小心谨慎地过日子,唯有元宵节这天可以纵情豪放一把.东风夜放花千树,宝马雕车香满路,火树银花霓虹闪烁,豪车遍地美女如云.细品,你甚至都能嗅到香奈儿的味道!月上柳梢头,人约黄昏后,这又是何等的浪漫!比起烛光晚宴.鲜花加持,这份浪漫更显纯真.晚至明清,民间元宵节的喜庆气氛,堪比西班牙的奔牛节.巴西的狂欢节.泰国的泼水节. 由于众所周知的原因,估计今年的趵突泉元宵节灯会又要黄了.去哪儿体验"花市灯如昼"的节日

  • Python OpenGL绘制一场烟花盛会

    目录 1. 安装WxGL 2. 快速体验 3. 编写自己的着色器 4. 绽放的烟花 忙碌了一年,今天终于放假了.原本打算好好休息一下,没成想只过了半天就觉得有点无聊.看家人和朋友们都在忙年,那我就用OpenGL导演一场烟花盛会,献给即将到来的新年吧. 一说到OpenGL,很多人都会觉得复杂,其实不然.只要掌握了几个基本的概念,借助于工具软件,任何人都可以很轻松地上手.在制作烟花之前,我先介绍一下WxGL这个三维数据快速可视化工具. 1. 安装WxGL WxGL是一个基于PyOpenGL的三维数据

  • Python+OpenGL制作一个元宵花灯

    目录 1.准备 2.快速体验 3.模型动画 4.子图布局 5.颜色映射 6.走马灯 又是一年元宵节,作为程序员的你,打算怎么过呢?如果昨天情人节的红包发得手软又心疼,不妨静下心来,了解一下三维数据可视化,顺便做一盏花灯送给女朋友,也许比红包更能讨她欢心呢. 1.准备 三维数据快速可视化工具,我喜欢用WxGL.这是一个基于PyOpenGL的三维数据可视化库,提供类似Matplotlib风格的3D绘图函数.如果熟悉NumPy和Matplotlib的话,只需要几分钟时间就可以学会使用WxGL的交互式绘

  • 小 200 行 Python 代码制作一个换脸程序

    简介 在这篇文章中我将介绍如何写一个简短(200行)的 Python 脚本,来自动地将一幅图片的脸替换为另一幅图片的脸. 这个过程分四步: 检测脸部标记. 旋转.缩放.平移和第二张图片,以配合第一步. 调整第二张图片的色彩平衡,以适配第一张图片. 把第二张图像的特性混合在第一张图像中. 1.使用 dlib 提取面部标记 该脚本使用 dlib 的 Python 绑定来提取面部标记: Dlib 实现了 Vahid Kazemi 和 Josephine Sullivan 的<使用回归树一毫秒脸部对准>

  • 十行Python代码制作一个视频倒放神器

    目录 导语 正文 源码如下 效果展示 总结 补充 导语 大家好,我是栗子同学! 今天给大家分享一个好玩的东西 让时光倒流——当当当,其实就是让视频倒放而已 正常的视频如下 倒放视频如下 效果很赞吧,等你学会了这个,你才会发现,抖音上那些杯子里的水倒流,倒着跑步等看似很炫酷很神秘的视频,其实就是一键倒放而已! 那么,今天小编就来探索Python代码如何实现这个倒放的功能叭~ 正文 这些搞笑的gif跟小视频都是将正常的流畅通过倒放产生的效果啦 其实制作起来却非常简单,原理就是将gif图片拆分出来每一

  • Python+PyQt5制作一个图片查看器

    目录 前言 实现方式 测试 前言 在 PyQt 中可以使用很多方式实现照片查看器,最朴素的做法就是重写 QWidget 的 paintEvent().mouseMoveEvent 等事件,但是如果要在图像上多添加一些形状,那么在对图像进行缩放旋转等仿射变换时需要对这些形状也这些变换,虽然不难,但是从头实现这些变换还有形状还是挺讨厌的.好在 Qt 提供了图形视图框架,关于这个框架的基本使用可以参见 深入了解PyQt5中的图形视图框架,下面进入正题. 实现方式 一个最基本的照片查看器应该具有以下功能

  • 利用Python+Excel制作一个视频下载器

    说起Excel,那绝对是数据处理领域王者般的存在. 而作为网红语言Python,在数据领域也是被广泛使用. 其中Python的第三方库-xlwings,一个Python和Excel的交互工具,可以轻松地通过VBA来调用Python脚本,实现复杂的数据分析. 今天,小F就给大家介绍一个Python+Excel的项目[视频下载器]. 主要使用到下面这些Python库. import os import sys import ssl import ffmpeg import xlwings as xw

  • Python+ChatGPT制作一个AI实用百宝箱

    目录 注册OpenAI 搭建网站及其框架 AI聊天机器人 AI绘画机器人 ChatGPT最近在互联网掀起了一阵热潮,其高度智能化的功能能够给我们现实生活带来诸多的便利,可以帮助你写文章.写报告.写周报.做表格.做策划甚至还会写代码.只要与文字相关的工作,它几乎都能给出一份满意的答卷. 小编趁着有空上去玩了一下,也发现了其中的强大 那么本篇文章小编就通过streamlit框架来搭建一个AI百宝箱的网页,其中里面集成了一系列功能包括智能聊天机器儿.智能绘画师,大家有兴趣还可以另外添加例如配音等功能,

  • 基于Python轻松制作一个股票K线图网站

    目录 获取股票数据 PyEcharts 作图 构建 Web 框架 视图函数编写 模板编写 编辑主逻辑 前端页面编写 在前面的文章中,我们学习了如何使用 Tkinter 构建股票数据抓取以及展示K线图功能,虽然大致的功能已经具备,但是在当今这个人手一个 Web 服务的年代,GUI 程序还是没有 Web 服务来的香啊. 我们需要用到的知识包括 PyEcharts 的使用,tushare 库获取股票数据的方法以及 Flask 的基本用法. 获取股票数据 我们先来看下 tushare 的使用,这个应该是

  • 小白如何入门Python? 制作一个网站为例

    首先最重要的问题是为什么要学习python?这个问题这个将指导你如何学习Python和学习的方式. 以你最终想制作一个网站为例.从一个通用的学习资源列表开始不仅会消磨你的激情,而且你获得的知识很难应用,我曾经尝试过不通过上下文和具体应用来学习编程,但是我几乎没有获得任何有用的技能. 当我3年前学习python时,我想创建一个网站.这对于任何一个学习Pyhon人来说,不足为奇. 1.找到是什么激励你 找到并保持你的动机是关键-我高中睡了很多个的程序设计课,因为它只让我们记住了一堆语法.另一方面,当

  • 使用python制作一个为hex文件增加版本号的脚本实例

    最近公司一个项目需要用到IAP升级,要求将APP的版本号在hex文件添加,于是尝试用python写一个脚本,运行之后可以自动增加版本号,并且日期都是当天的 import re import time #获取日期的数据及校验和 year = int(time.strftime("%y", time.localtime())) month = int(time.strftime("%m", time.localtime())) date = int(time.strft

  • 使用Python制作一个打字训练小工具

    一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码. 然而现实中的程序员呢?对于很多程序员来说,没有百度和 Google 解决不了的问题,也没有 ctrl + c 和 ctrl + v 实现不了的功能. 那么身为一个程序员,要怎么让自己看起来更加"专业"呢?答案就是加快自己的打字速度了,敲的代码可能是错的,但这个13却是必须装的! 然而还

随机推荐