May 30, 2021 Article blog
Speaking of Lantern Festival, do you think this is the most romantic festival we Chinese? T he Chinese people have always been rigid, all year round are careful to live, only the Lantern Festival this day can indulge in a grand. D ongfeng night flowers thousands of trees, BMW carved cars full of roads, fire trees silver neon flashing, luxury cars everywhere beautiful like clouds. F ine products, you can even smell Chanel! O n the moon willow head, people about after dusk, this is how romantic! T his romance is more innocent than candlelight dinners and flowers. Late to the Ming and Qing Dynasties, the festive atmosphere of the folk Lantern Festival is comparable to spain's Bull Run Festival, Brazil's Carnival, Thailand's Water Splash Festival.
For well-known reasons, it is estimated that this year's Lantern Festival lights will be yellow again. W here to experience the festive atmosphere of "flower market lights like day"? Don't worry, nothing can upset programmers - 3D technology can also make the following picture of the horse lamp, is better than nothing.
As shown below, you can also add your favorite patterns, text, etc.
A computer with a Python environment installed, and the Python environment requires the following modules to be installed.
numpy
pillow
wxgl
If you do not have the modules above, please refer to the command below to install them.
pip install numpy
pip install pillow
pip install wxgl
NumPy and pillow are Python's most commonly used scientific computing and image processing libraries and are common modules. W
xGL is a PyOpenGL-based 3D data visualization library that uses wx as the display back end to provide Matplotlib-style interactive application mode, while also seamlessly combining with wxPython to draw 3D models on wx forms.
The lamp-making process is simple, requiring only thirty lines of code and can be executed interactively line by line directly in Python IDLE.
>>> import numpy as np
>>> from PIL import Image
>>> import wxgl.wxplot as plt
>>> fn = r'D:\temp\light0115\res\paper.png'
>>> im = np.array(Image.open(fn))/255
>>> im.shape
(400, 942, 3)
fn defines the image storage path, please modify it as a result.
Image.open(fn)
opens the file and returns a PIL object,
np.array()
turns the PIL object into a
numpy.ndarray
array object. D
ivide by 255 to change the range of image data from 0 to 255 to 0 to 1, adapting to WxGL's interface requirements.
Look at the shape of the array to show an image resolution of 400 pixels high, 942 pixels wide, and three colors per pixel (RGB in this case).
The paper is 942 pixels long, rolled into cylinders, and has a radius of 149.9 pixels, which is equivalent to 2.668 units at a height of 400 pixels if the radius is considered to be one unit.
>>> rows, cols, deep = im.shape
>>> cols/(2*np.pi)
149.9239563925654
>>> r = 1
>>> h = 2*np.pi*rows/cols
>>> h
2.6680192387174464
The next step is to make a cyrus-shaped keel with a radius of 1 unit and a height of 2.668 units.
>>> theta = np.linspace(0, 2*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))
Here
xs
ys,
zs
are the x
ys
z coordinates of each point on the cylindrical keel. T
he following code draws 1 point every 10 points and draws the keel shape with
mesh
O
f course, you can also draw all the points, so that the vertices will be connected together.
>>> plt.mesh(xs[::10,::10], ys[::10,::10], zs[::10,::10], mode='FLBL')
>>> plt.show()
The keel, drawn in 3D, works as follows.
With the keel, you can then attach the lantern paper to the keel. Before proceeding, remember to close the 3D keel window that just popped up.
>>> plt.mesh(xs, ys, zs, im)
>>> plt.show()
However, you will immediately find that the lamp paper up and down the opposite direction. I
t doesn't matter, we can reverse the direction like this.
>>> plt.mesh(xs, ys, zs, im[::-1])
>>> plt.show()
Well, isn't there a little bit of a horse lamp prototype?
The horse lamp can be turned because there are candles inside to heat up the air flow, pushing the top impeller to rotate, thus driving the lantern to rotate. Of course, the impeller here is just a look, and the rotation of the lanterns depends on another mechanism.
>>> theta = np.linspace(0, 2*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()
The impeller design has 6 pieces, simulated with triangles, dark red color, transparency 0.8, the overall effect is slightly rougher.
The light is represented by a white ball, and the lift is a straight red line that acts as a power cord for the light.
>>> 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')
The implementation of the lantern rotation is very simple, just give
show
method a
rotation
parameter.
plt.show(rotation='h-')
The final effect of the lanterns is as follows.
With the above explanation, the complete source code need not be commented. With more than thirty lines of code, you can expand yourself to create more lanterns.
# -*- 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 = 1, 2*np.pi*rows/cols
theta = np.linspace(0, 2*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(0, 2*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-')
Recommended good lessons: python3 getting started, python3 advanced
Source: CSDN
Author: Tianyuan Prodigal Son
Original title: Lantern Festival is coming, do you want a lantern? 3D kind
Original address: https://xufive.blog.csdn.net/article/details/114058247