It's 520 again, let's draw a twitching rose

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

insert image description here

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)=121(1Pimod ( 3.6 t ,2 p ).)4=2(x2x)2sinp=u(xsinp+ycosp)=rcost=rsint=u(xcospysinp)

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}; 1000CiSi0SiCi [ 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}; Ci0Si010Si0Ci [ 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}; CiSi0SiCi0001

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

Please add a picture description

Guess you like

Origin blog.csdn.net/m0_37816922/article/details/130771170