Python+OpenGL制作一個元宵花燈
又是一年元宵節(jié),作為程序員的你,打算怎么過呢?如果昨天情人節(jié)的紅包發(fā)得手軟又心疼,不妨靜下心來,了解一下三維數(shù)據(jù)可視化,順便做一盞花燈送給女朋友,也許比紅包更能討她歡心呢。
1.準(zhǔn)備
三維數(shù)據(jù)快速可視化工具,我喜歡用WxGL。這是一個基于PyOpenGL的三維數(shù)據(jù)可視化庫,提供類似Matplotlib風(fēng)格的3D繪圖函數(shù)。如果熟悉NumPy和Matplotlib的話,只需要幾分鐘時間就可以學(xué)會使用WxGL的交互式繪圖。
WxGL模塊使用pip命令安裝。
pip install wxgl
安裝完成后,可以在Python IDLE中查看版本信息。
>>> import wxgl >>> wxgl.version '0.8.5'
2.快速體驗
元宵、花燈和月亮,是元宵節(jié)的三大主題元素。我們就以一個文藝范兒的月亮開啟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球面函數(shù)繪制了一個中心點在三維坐標(biāo)系原點、半徑為1的月亮。忽略模塊名的話,這些代碼和Matplotlib的風(fēng)格幾乎是完全一致的,甚至函數(shù)名都是相同的。
運行show函數(shù)會彈出一個窗口,顯示繪制的模型。窗口底部提供了一組工具按鈕,可以設(shè)置系統(tǒng)參數(shù)、切換畫布風(fēng)格、顯示或隱藏坐標(biāo)網(wǎng)格、播放動畫、保存或錄制屏幕等。和Matplotlib一樣,該窗口將阻塞程序運行,直至關(guān)閉該窗口。
3.模型動畫
通過transform參數(shù)傳遞一個以時間長度為參數(shù)的函數(shù)給uvsphere球面函數(shù),就可以讓上面的月亮轉(zhuǎn)動起來。
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 # 關(guān)閉燈光效果,環(huán)境光會自動增強(qiáng) ) 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()
代碼中l(wèi)ambda函數(shù)——當(dāng)然也可以是普通的函數(shù),其參數(shù)duration是以毫秒為單位的時間長度。該函數(shù)返回月球圍繞一個向量(此處為(0,1,0),即y軸)旋轉(zhuǎn)的角度。點擊播放按鈕,月球即開始以20°/s的速度旋轉(zhuǎn)。
對了,差點兒忘記提供月球的紋理圖片了。點擊此處可下載不帶水印的月球紋理圖片。
4.子圖布局
在一張畫布上可以任意放置多個子圖。下面的代碼演示了子圖布局函數(shù)subplot的經(jīng)典用法。實際上,這個函數(shù)比Matplotlib的同名函數(shù)更靈活和便捷。
import wxgl.wxplot as plt plt.subplot(121) plt.title('經(jīng)緯度網(wǎng)格生成球體') plt.uvsphere((0,0,0), 1, color='coral', fill=False, slices=15) plt.subplot(122) plt.title('正八面體迭代細(xì)分生成球體') plt.isosphere((0,0,0), 1, color='cyan', fill=False, iterations=2) plt.show()
在畫布上創(chuàng)建兩個子圖,使用兩種不同的方式繪制球,并設(shè)置填充模式。由于使用相同的視點系統(tǒng),兩個子圖上的模型可以保持同步。
5.顏色映射
對于數(shù)據(jù)快速可視化工具來說,顏色映射是必不可少的。下面的代碼演示了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函數(shù)和colorbar函數(shù)示例') plt.show()
WxGL允許在一張圖上使用兩個垂直風(fēng)格的ColorBar和三個水平風(fēng)格的ColorBar。
6.走馬燈
去年元宵節(jié)我寫過一篇繪制3D花燈的博客,用的工具也是WxGL,當(dāng)時的版本還是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),) # 模型動畫函數(shù) # 以下生成花燈筒狀龍骨 theta = np.linspace(0, 2*np.pi, 361) # 在0°~360°范圍內(nèi)間隔1°均勻生成361個角度 xs = r * np.tile(np.cos(theta), (150,1)) # 半徑為r的圓周上361點的x坐標(biāo),重復(fù)150次,得到150行361列的二維數(shù)組 zs = r * np.tile(-np.sin(theta), (150,1)) # 半徑為r的圓周上361點的z坐標(biāo),重復(fù)150次,得到150行361列的二維數(shù)組 ys = np.repeat(np.linspace(2.7, 0, 150), 361).reshape(150,361) # 0~2.7范圍內(nèi)均勻生成150個點,每個重復(fù)361,得到150行361列的二維數(shù)組 # 以下生成花燈葉輪 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) # 公牛動畫函數(shù):順時針旋轉(zhuǎn),20°/s,向左平移1.2 tf_bull = lambda duration : ((0, 1, 0, (-0.02*duration)%360), (-1.2,0,0)) # 老虎動畫函數(shù):逆時針旋轉(zhuǎn),20°/s,向右平移1.2 tf_tiger = lambda duration : ((0, 1, 0, (0.02*duration)%360), (1.2,0,0)) plt.figure(elev=20) # 設(shè)置相機(jī)高度角為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()
兩只花燈使用相同的尺寸,畫在同一個位置?;敉埠腿~輪的模型動畫函數(shù)除了旋轉(zhuǎn)還分別向左右移動了1.2個長度單位,而燈和線則只移動不旋轉(zhuǎn)。最終效果如下圖所示。
到此這篇關(guān)于Python+OpenGL制作一個元宵花燈的文章就介紹到這了,更多相關(guān)Python OpenGL元宵花燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python利用pyHook實現(xiàn)監(jiān)聽用戶鼠標(biāo)與鍵盤事件
這篇文章主要介紹了Python利用pyHook實現(xiàn)監(jiān)聽用戶鼠標(biāo)與鍵盤事件,很有實用價值的一個技巧,需要的朋友可以參考下2014-08-08Python中的列表生成式與生成器學(xué)習(xí)教程
這篇文章主要介紹了Python中的列表生成式與生成器學(xué)習(xí)教程,Python中的Generator生成器比列表生成式功能更為強(qiáng)大,需要的朋友可以參考下2016-03-03Python實現(xiàn)PS濾鏡的旋轉(zhuǎn)模糊功能示例
這篇文章主要介紹了Python實現(xiàn)PS濾鏡的旋轉(zhuǎn)模糊功能,涉及Python基于skimage庫針對圖片進(jìn)行旋轉(zhuǎn)與模糊化處理的相關(guān)操作技巧,需要的朋友可以參考下2018-01-01MxNet預(yù)訓(xùn)練模型到Pytorch模型的轉(zhuǎn)換方式
這篇文章主要介紹了MxNet預(yù)訓(xùn)練模型到Pytorch模型的轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05python反反爬蟲技術(shù)限制連續(xù)請求時間處理
這篇文章主要為大家介紹了python反反爬蟲技術(shù)限制連續(xù)請求時間處理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06在jupyter notebook 添加 conda 環(huán)境的操作詳解
這篇文章主要介紹了在jupyter notebook 添加 conda 環(huán)境的操作詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python3.7+tkinter實現(xiàn)查詢界面功能
這篇文章主要介紹了Python3.7+tkinter實現(xiàn)查詢界面功能,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12Python + opencv對拍照得到的圖片進(jìn)行背景去除的實現(xiàn)方法
這篇文章主要介紹了Python + opencv對拍照得到的圖片進(jìn)行背景去除的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11