• 售前

  • 售后

热门帖子
入门百科

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

[复制链接]
墙和鸡蛋 显示全部楼层 发表于 2021-10-25 20:33:26 |阅读模式 打印 上一主题 下一主题
说起元宵节,各位有没有以为这是咱们中国人最浪漫的节日呢?国人向来拘谨古板,一年到头都是胆小如鼠地过日子,唯有元宵节这天可以纵情豪放一把。东风夜放花千树,宝马雕车香满路,火树银花霓虹闪耀,豪车各处玉人如云。细品,你乃至都能嗅到香奈儿的味道!月上柳梢头,人约薄暮后,这又是多么的浪漫!比起烛光晚宴、鲜花加持,这份浪漫更显单纯。晚至明清,民间元宵节的喜庆气氛,堪比西班牙的奔牛节、巴西的狂欢节、泰国的泼水节。
由于众所周知的缘故原由,估计今年的趵突泉元宵节灯会又要黄了。去哪儿体验“花市灯如昼”的节日气氛呢?Don't worry,没有什么事能够难倒步调员——用3D技能也可以做出下图这样的走马灯,算是聊胜于无吧。

1.原质料

花灯纸
如下所示,还可以加上本身喜欢的图案、文字等。

Python情况和模块
一台安装了Python情况的电脑,Python情况需要安装以下模块。
      
  • numpy  
  • pillow  
  • wxgl
如果没有上述模块,请参考下面的下令安装。
  1. pip install numpy
  2. pip install pillow
  3. pip install wxgl
复制代码
NumPy和 pillow 是 Python 旗下最常用的科学盘算库和图像处理库,属于常用模块。WxGL 是一个基于 PyOpenGL 的三维数据可视化库,以 wx 为表现后端,提供 Matplotlib 风格的交互式应用模式,同时,也可以和 wxPython 无缝结合,在wx的窗体上绘制三维模子。
2.制作工序

花灯制作工序非常简单,只需要三十行代码,可以直接在Python IDLE中以交互方式逐行实行。
导入模块
  1. >>> import numpy as np
  2. >>> from PIL import Image
  3. >>> import wxgl.wxplot as plt
复制代码
打开花灯纸图像
  1. >>> fn = r'D:\temp\light0115\res\paper.png'
  2. >>> im = np.array(Image.open(fn))/255
  3. >>> im.shape
  4. (400, 942, 3)
复制代码
fn界说的是图像存储路径,请据实修改。Image.open(fn)打开文件,返回一个PIL对象,np.array()将PIL对象转成numpy.ndarray数组对象。除以255,将图像数据从0到255的值域范围酿成0到1,顺应WxGL的接口要求。查看数组的shape,表现图像分辨率为400像素高、942像素宽,每个像素有三种颜色(此处为RGB)。
根据花灯纸的巨细制作龙骨
纸长942像素,卷成圆筒,半径就是149.9像素,如果把半径视为1个单元,则高度400像素相当于2.668个单元。
  1. >>> rows, cols, deep = im.shape
  2. >>> cols/(2*np.pi)
  3. 149.9239563925654
  4. >>> r = 1
  5. >>> h = 2*np.pi*rows/cols
  6. >>> h
  7. 2.6680192387174464
复制代码
接下来需要制作半径1个单元、高度2.668个单元的圆筒状龙骨了。
  1. >>> theta = np.linspace(0, 2*np.pi, cols)
  2. >>> x = r * np.cos(theta)
  3. >>> y = r * np.sin(theta)
  4. >>> z = np.linspace(0, h, rows)
  5. >>> xs = np.tile(x, (rows,1))
  6. >>> ys = np.tile(y, (rows,1))
  7. >>> zs = z.repeat(cols).reshape((rows,cols))
复制代码
这里的xs、ys、zs就是圆筒状龙骨上各个点的x坐标、y坐标、z坐标。下面的代码,每隔10个点抽取1个点,用mesh的方法画出龙骨形状。固然,也可以画出全部的点,那样极点就会连成一片。
  1. >>> plt.mesh(xs[::10,::10], ys[::10,::10], zs[::10,::10], mode='FLBL')
  2. >>> plt.show()
复制代码
用3D的方式画出来的龙骨,效果如下。

给龙骨贴上花灯纸
有了龙骨,接下来就可以把花灯纸贴在龙骨上了。继承操纵之前,记得先把刚才弹出的3D龙骨窗口关闭。
  1. >>> plt.mesh(xs, ys, zs, im)
  2. >>> plt.show()
复制代码
不外,你会立刻发现,花灯纸上下方向贴反了。没关系,我们可以像下面这样反转方向。
  1. >>> plt.mesh(xs, ys, zs, im[::-1])
  2. >>> plt.show()
复制代码
怎么样,是不是有一点走马灯的雏形了呢?

制作旋转叶轮
走马灯之所以能够转动,是由于里面有蜡烛加热形成上升气流,推动顶部的叶轮旋转,从而带动花灯旋转。固然,这里的叶轮仅仅是个样子,花灯旋转依靠别的的机制实现。
  1. >>> theta = np.linspace(0, 2*np.pi, 18, endpoint=False)
  2. >>> x = r * np.cos(theta)
  3. >>> y = r * np.sin(theta)
  4. >>> x[2::3] = x[1::3]
  5. >>> x[1::3] = 0
  6. >>> y[2::3] = y[1::3]
  7. >>> y[1::3] = 0
  8. >>> z = np.ones(18) * h * 0.9
  9. >>> vs = np.stack((x,y,z), axis=1)
  10. >>> plt.mesh(xs, ys, zs, im[::-1])
  11. >>> plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
  12. >>> plt.show()
复制代码
叶轮设计有6片,用三角形模拟,颜色深红,透明度0.8,整体效果略显粗糙了一点。

加上照明灯和提系
照明灯用一个白色的圆球表现,提系则是赤色的一条直线,兼做照明灯的电源线。
  1. >>> plt.mesh(xs, ys, zs, im[::-1])
  2. >>> plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
  3. >>> plt.sphere((0,0,h*0.4), 0.4, '#FFFFFF', slices=60, mode='FCBC')
  4. >>> plt.plot((0,0), (0,0), (0.4*h, 1.5*h), width=3.0, style='solid', cmap='hsv', caxis='z')
复制代码
让花灯转起来
花灯旋转的实现非常简单,只需要给show方法一个rotation参数就可以。
  1. plt.show(rotation='h-')
复制代码
最终的花灯效果如下。

3.完备代码
  1. # -*- coding: utf-8 -*-
  2. import numpy as np
  3. from PIL import Image
  4. import wxgl.wxplot as plt
  5. im = np.array(Image.open('res/paper.png'))/255
  6. rows, cols, deep = im.shape
  7. r, h = 1, 2*np.pi*rows/cols
  8. theta = np.linspace(0, 2*np.pi, cols)
  9. x = r*np.cos(theta)
  10. y = r*np.sin(theta)
  11. z = np.linspace(0, h, rows)
  12. xs = np.tile(x, (rows,1))
  13. ys = np.tile(y, (rows,1))
  14. zs = z.repeat(cols).reshape((rows,cols))
  15. theta = np.linspace(0, 2*np.pi, 18, endpoint=False)
  16. x = r*np.cos(theta)
  17. y = r*np.sin(theta)
  18. x[2::3] = x[1::3]
  19. x[1::3] = 0
  20. y[2::3] = y[1::3]
  21. y[1::3] = 0
  22. z = np.ones(18) * h * 0.9
  23. vs = np.stack((x,y,z), axis=1)
  24. plt.mesh(xs, ys, zs, im[::-1])
  25. plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
  26. plt.sphere((0,0,h*0.4), 0.4, '#FFFFFF', slices=60, mode='FCBC')
  27. plt.plot((0,0), (0,0), (0.4*h, 1.5*h), width=3.0, style='solid', cmap='hsv', caxis='z')
  28. plt.show(rotation='h-')
复制代码
到此这篇关于使用Python制作一盏 3D 花灯喜迎元宵佳节的文章就先容到这了,更多相干Python制作 3D 花灯内容请搜索脚本之家从前的文章或继承欣赏下面的相干文章渴望大家以后多多支持脚本之家!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作