Article directory
After so many years of coding, I have to draw some hearts, flowers and so on every year, so now the conventional ones are a bit tired, at least I need a 3D graphic to make it look more reasonable, and just 3D is not interesting, It's better to be able to move.
static rose
There are many codes for generating roses on the Internet, such as the following
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
[x,t]=np.meshgrid(np.arange(25)/24.0,
np.arange(0,575.5,0.5)/575*17*np.pi-2*np.pi)
p=(np.pi/2)*np.exp(-t/(8*np.pi))
u=1-(1-np.mod(3.6*t,2*np.pi)/np.pi)**4/2
y=2*(x**2-x)**2*np.sin(p)
r=u*(x*np.sin(p)+y*np.cos(p))
X,Y = r*np.cos(t), r*np.sin(t)
Z = u*(x*np.cos(p)-y*np.sin(p))
ax=plt.subplot(projection='3d')
ax.plot_surface(X, Y, Z, lw=0, rstride=1,
cstride=1,cmap=cm.gist_rainbow_r)
plt.axis('off')
plt.show()
The effect is as follows
Its formula is
p = π 2 exp ( − t 8 π ) u = 1 − 1 2 ( 1 − mod ( 3.6 t , 2 π ) π ) 4 y = 2 ( x 2 − x ) 2 sin pr = u ( x sin p + y cos p ) X = r cos t Y = r sin t Z = u ( x cos p − y sin p ) \begin{aligned} p &= \frac{\pi}{ 2}\exp(-\frac{t}{8\pi})\\ u &= 1-\frac{1}{2}(1-\frac{\operatorname{mod}(3.6t, 2\pi )}{\pi})^4\\ y &= 2(x^2-x)^2\sin p\\ r &= u(x\sin p+y\cos p)\\ X &= r \cos t\\ Y &= r\sin t\\ Z &= u(x\cos py\sin p) \end{aligned}puyrXYZ=2pexp(−8 p.mt)=1−21(1−Pimod ( 3.6 t ,2 p ).)4=2(x2−x)2sinp=u(xsinp+ycosp)=rcost=rsint=u(xcosp−ysinp)
rotating rose
However, if there is only this one flower, even if the color is very gorgeous, it will feel boring after a long time, so let’s add a little action to this picture, such as making the flower rotate in space, the method is very simple, just multiply The previous rotation matrix is OK. For writing convenience, record S θ = sin θ , C θ = cos θ S_\theta=\sin\theta, C_\theta=\cos\thetaSi=sini ,Ci=cosθ , can be listed in the following table.
R x ( θ ) R_x(\theta) Rx( i ) | R x ( θ ) R_x(\theta)Rx( i ) | R x ( θ ) R_x(\theta)Rx( i ) |
---|---|---|
[ 1 0 0 0 C θ − S θ 0 S θ C θ ] \begin{bmatrix}1&0&0\\0&C_\theta&-S_\theta\\0&S_\theta&C_\theta\\\end{bmatrix}; 1000CiSi0−SiCi | [ C θ 0 S θ 0 1 0 − S θ 0 C θ ] \begin{bmatrix}C_\theta&0 &S_\theta\\0&1&0\\-S_\theta&0&C_\theta\\\end{bmatrix}; Ci0−Si010Si0Ci | [ C θ S θ 0 − S θ C θ 0 0 0 1 ] \begin{bmatrix}C_\theta &S_\theta&0\\-S_\theta&C_\theta&0\\0&0&1\end{bmatrix}; Ci−Si0SiCi0001 |
The meaning of the following code is that the rose rotates around the Z axis.
from matplotlib import animation
import imageio
cos = lambda th : np.cos(np.deg2rad(th))
sin = lambda th : np.sin(np.deg2rad(th))
# 此为旋转矩阵
Rz = lambda th : np.array([
[cos(th) , -sin(th), 0],
[sin(th), cos(th), 0],
[0 , 0, 1]])
xyz = np.array([X,Y,Z]).reshape(3,-1)
gifImgs = []
for n in np.arange(0,30,1):
xd,yd,zd = (Rx(n)@Ry(n)@Rz(n)@xyz).reshape(3,1151,25)
ax = plt.subplot(projection='3d')
ax.plot_surface(xd,yd,zd, lw=0, rstride=1,
cstride=1,cmap=cm.gist_rainbow_r)
plt.axis('off')
plt.savefig("%d.jpg" % n)
gifImgs.append(imageio.imread("%d.jpg" % n))
imageio.mimsave("test.gif",gifImgs,fps=5)
ani = animation.FuncAnimation(fig, animate,
range(0, 360, 2), interval=25, blit=True)
#plt.show()
ani.save("zyx.gif")
But the final effect is not ideal, it seems to be twitching, it feels very bizarre