<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          元宵節(jié)就要到了,手把手教你用Python打造一款3D花燈

          共 5720字,需瀏覽 12分鐘

           ·

          2021-02-28 09:17

          點擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進行關注

          回復“書籍”即可獲贈Python從入門到進階共10本電子書

          獨有宦游人,偏驚物候新。

          1 前言

          說起元宵節(jié),各位有沒有覺得這是咱們中國人最浪漫的節(jié)日呢?國人向來拘謹古板,一年到頭都是小心謹慎地過日子,唯有元宵節(jié)這天可以縱情豪放一把。東風夜放花千樹,寶馬雕車香滿路,火樹銀花霓虹閃爍,豪車遍地美女如云。細品,你甚至都能嗅到香奈兒的味道!月上柳梢頭,人約黃昏后,這又是何等的浪漫!比起燭光晚宴、鮮花加持,這份浪漫更顯純真。晚至明清,民間元宵節(jié)的喜慶氣氛,堪比西班牙的奔牛節(jié)、巴西的狂歡節(jié)、泰國的潑水節(jié)。
          由于眾所周知的原因,估計今年的趵突泉元宵節(jié)燈會又要黃了。去哪兒體驗“花市燈如晝”的節(jié)日氣氛呢?Don't worry,沒有什么事能夠難倒程序員——用3D技術也可以做出下圖這樣的走馬燈,算是聊勝于無吧。

          2 原材料

          2.1 花燈紙

          如下所示,還可以加上自己喜歡的圖案、文字等。

          2.2 Python環(huán)境和模塊

          一臺安裝了Python環(huán)境的電腦,Python環(huán)境需要安裝以下模塊。
          • numpy

          • pillow

          • wxgl

          如果沒有上述模塊,請參考下面的命令安裝。
          pip install numpy
          pip install pillow
          pip install wxgl
          NumPy和pillow是Python旗下最常用的科學計算庫和圖像處理庫,屬于常用模塊。WxGL是一個基于PyOpenGL的三維數(shù)據(jù)可視化庫,以wx為顯示后端,提供Matplotlib風格的交互式應用模式,同時,也可以和wxPython無縫結合,在wx的窗體上繪制三維模型。關于WxGL的更多信息,請參閱我的另一篇博客《十分鐘玩轉3D繪圖:WxGL完全手冊》。

          3 制作工序

          花燈制作工序非常簡單,只需要三十行代碼,可以直接在Python IDLE中以交互方式逐行執(zhí)行。

          3.1 導入模塊

          >>> import numpy as np
          >>> from PIL import Image
          >>> import wxgl.wxplot as plt

          3.2 打開花燈紙圖像

          >>> fn = r'D:\temp\light0115\res\paper.png'
          >>> im = np.array(Image.open(fn))/255
          >>> im.shape
          (4009423)
          fn定義的是圖像存儲路徑,請據(jù)實修改。Image.open(fn)打開文件,返回一個PIL對象,np.array()將PIL對象轉成numpy.ndarray數(shù)組對象。除以255,將圖像數(shù)據(jù)從0到255的值域范圍變成0到1,適應WxGL的接口要求。查看數(shù)組的shape,顯示圖像分辨率為400像素高、942像素寬,每個像素有三種顏色(此處為RGB)。

          3.3 根據(jù)花燈紙的大小制作龍骨

          紙長942像素,卷成圓筒,半徑就是149.9像素,如果把半徑視為1個單位,則高度400像素相當于2.668個單位。
          >>> rows, cols, deep = im.shape
          >>> cols/(2*np.pi)
          149.9239563925654
          >>> r = 1
          >>> h = 2*np.pi*rows/cols
          >>> h
          2.6680192387174464
          接下來需要制作半徑1個單位、高度2.668個單位的圓筒狀龍骨了。
          >>> theta = np.linspace(02*np.pi, cols)
          >>> x = r * np.cos(theta)
          >>> y = r * np.sin(theta)
          >>> z = np.linspace(0, h, rows)
          >>> xs = np.tile(x, (rows,1))
          >>> ys = np.tile(y, (rows,1))
          >>> zs = z.repeat(cols).reshape((rows,cols))
          這里的xs、ys、zs就是圓筒狀龍骨上各個點的x坐標、y坐標、z坐標。下面的代碼,每隔10個點抽取1個點,用mesh的方法畫出龍骨形狀。當然,也可以畫出全部的點,那樣頂點就會連成一片。
          >>> plt.mesh(xs[::10,::10], ys[::10,::10], zs[::10,::10], mode='FLBL')
          >>> plt.show()
          用3D的方式畫出來的龍骨,效果如下。

          3.4 給龍骨貼上花燈紙

          有了龍骨,接下來就可以把花燈紙貼在龍骨上了。繼續(xù)操作之前,記得先把剛才彈出的3D龍骨窗口關閉。
          >>> plt.mesh(xs, ys, zs, im)
          >>> plt.show()
          不過,你會立刻發(fā)現(xiàn),花燈紙上下方向貼反了。沒關系,我們可以像下面這樣反轉方向。
          >>> plt.mesh(xs, ys, zs, im[::-1])
          >>> plt.show()
          怎么樣,是不是有一點走馬燈的雛形了呢?

          3.5 制作旋轉葉輪

          走馬燈之所以能夠轉動,是因為里面有蠟燭加熱形成上升氣流,推動頂部的葉輪旋轉,從而帶動花燈旋轉。當然,這里的葉輪僅僅是個樣子,花燈旋轉依賴另外的機制實現(xiàn)。
          >>> theta = np.linspace(02*np.pi, 18, endpoint=False)
          >>> x = r * np.cos(theta)
          >>> y = r * np.sin(theta)
          >>> x[2::3] = x[1::3]
          >>> x[1::3] = 0
          >>> y[2::3] = y[1::3]
          >>> y[1::3] = 0
          >>> z = np.ones(18) * h * 0.9
          >>> vs = np.stack((x,y,z), axis=1)
          >>> plt.mesh(xs, ys, zs, im[::-1])
          >>> plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
          >>> plt.show()
          葉輪設計有6片,用三角形模擬,顏色深紅,透明度0.8,整體效果略顯粗糙了一點。

          3.6 加上照明燈和提系

          照明燈用一個白色的圓球表示,提系則是紅色的一條直線,兼做照明燈的電源線。
          >>> plt.mesh(xs, ys, zs, im[::-1])
          >>> plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
          >>> plt.sphere((0,0,h*0.4), 0.4'#FFFFFF', slices=60, mode='FCBC')
          >>> plt.plot((0,0), (0,0), (0.4*h, 1.5*h), width=3.0, style='solid', cmap='hsv', caxis='z')

          3.7 讓花燈轉起來

          花燈旋轉的實現(xiàn)非常簡單,只需要給show方法一個rotation參數(shù)就可以。
          plt.show(rotation='h-')
          最終的花燈效果如下。

          4 完整源代碼

          有了上面的解說,完整的源代碼就不用注釋了。全部代碼三十余行,各位可自行擴展,制作出更多的花燈來。
          # -*- coding: utf-8 -*-

          import numpy as np
          from PIL import Image
          import wxgl.wxplot as plt

          im = np.array(Image.open('res/paper.png'))/255
          rows, cols, deep = im.shape

          r, h = 12*np.pi*rows/cols
          theta = np.linspace(02*np.pi, cols)
          x = r*np.cos(theta)
          y = r*np.sin(theta)
          z = np.linspace(0, h, rows)
          xs = np.tile(x, (rows,1))
          ys = np.tile(y, (rows,1))
          zs = z.repeat(cols).reshape((rows,cols))

          theta = np.linspace(02*np.pi, 18, endpoint=False)
          x = r*np.cos(theta)
          y = r*np.sin(theta)
          x[2::3] = x[1::3]
          x[1::3] = 0
          y[2::3] = y[1::3]
          y[1::3] = 0
          z = np.ones(18) * h * 0.9
          vs = np.stack((x,y,z), axis=1)

          plt.mesh(xs, ys, zs, im[::-1])
          plt.surface(vs, color='#C03000', method='T', mode='FCBC', alpha=0.8)
          plt.sphere((0,0,h*0.4), 0.4'#FFFFFF', slices=60, mode='FCBC')
          plt.plot((0,0), (0,0), (0.4*h, 1.5*h), width=3.0, style='solid', cmap='hsv', caxis='z')
          plt.show(rotation='h-')


          ------------------- End -------------------

          往期精彩文章推薦:

          歡迎大家點贊,留言,轉發(fā),轉載,感謝大家的相伴與支持

          想加入Python學習群請在后臺回復【入群

          萬水千山總是情,點個【在看】行不行

          /今日留言主題/

          隨便說一兩句吧~

          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男男精品一区二区三区 | 人人色人人黄 | 免费在线观看黄色视频链接 | 欧美成人精品在线播放 | 亚洲国产精品成人va在线观看 |