【编程与艺术的完美交融】创意绘制Python特色花束,献礼母亲节!

母亲节,这个充满爱与感恩的温馨节日,正是我们向母亲们表达敬意和深厚情感的黄金时刻。日常中,我们沉浸于代码的世界,编织出各种实用而有趣的程序。但今天,我诚挚地邀请各位宝子一同踏上这段独特的旅程,用Python编程语言亲手绘制出一束绚丽多姿的虚拟花束。这不仅仅是一串代码,更是我们对母爱无尽的赞美与感激的诠释。

在接下来的篇幅中,我将分享绘制这束特别的虚拟花束的所需要的库和完整代码。希望通过我的分享,能带领各位宝子更加感受到编程的魅力,同时也能够体会到母爱的伟大与无私。

在绘制这束特殊花束之前,我们需要确保安装了必要的Python库。这些库包括matplotlib(用于绘图)、numpy(用于数值计算)和scipy(一个用于数学、科学和工程的开源Python库)。各位宝子可以使用pip来安装这些库,在终端输入以下命令行下载即可:

pip install numpy
pip install matplotlib  
pip install scipy

 完整代码如下:

import matplotlib.pyplot as plt  
import numpy as np  
from matplotlib.colors import LinearSegmentedColormap as lsc  
from scipy.spatial.transform import Rotation as R  
# @author : 码海航行的小李  
  
# 生成花朵数据  
# t1 用于生成花瓣的径向坐标,t2 用于生成花瓣的角向坐标  
t1 = np.array(range(25))/24  
t2 = np.arange(0, 575.5, 0.5)/575*20*np.pi + 4*np.pi  
[xr, tr] = np.meshgrid(t1, t2)  
  
# 根据 t1 和 t2 计算出花瓣的形状  
pr = (np.pi/2)*np.exp(-tr/(8*np.pi))  
ur = 1 - (1 - np.mod(3.6*tr, 2*np.pi)/np.pi)**4/2 + np.sin(15*tr)/150 + np.sin(15*tr)/150  
yr = 2*(xr**2 - xr)**2*np.sin(pr)  
rr = ur*(xr*np.sin(pr) + yr*np.cos(pr))  
hr = ur*(xr*np.cos(pr) - yr*np.sin(pr))  
  
# 生成花心的数据  
tb = np.resize(np.linspace(0, 2, 151), (1,151))  
rb = np.resize(np.linspace(0, 1, 101), (101,1)) @ ((abs((1-np.mod(tb*5,2))))/2 + .3)/2.5  
xb = rb*np.cos(tb*np.pi)  
yb = rb*np.sin(tb*np.pi)  
hb = np.power(-np.cos(rb*1.2*np.pi)+1, .2)  
  
# 定义颜色映射  
# cL 是原始颜色列表,但由于后续赋值,实际使用的颜色列表是第二个 cL  
cL = np.array([[.33,.33,.69], [.68,.42,.63], [.78,.42,.57], [.96,.73,.44]])  
cL = np.array([[.02,.04,.39], [.02,.06,.69], [.01,.26,.99], [.17,.69,1]])  
cMpr = lsc.from_list('码海航行的小李', cL)  # 创建名为 '码海航行的小李' 的颜色映射  
cMpb = lsc.from_list('码海航行的小李_淡', cL*.4 + .6)  # 创建颜色较淡的颜色映射  
  
# 绕轴旋转数据点  
def rT(X, Y, Z, T):  
    """  
    绕给定角度 T 旋转三维数据点 X, Y, Z  
    :param X: x 轴坐标数组  
    :param Y: y 轴坐标数组  
    :param Z: z 轴坐标数组  
    :param T: 旋转角度(度)  
    :return: 旋转后的 x, y, z 坐标数组  
    """  
    SZ = X.shape  
    XYZ = np.hstack((X.reshape(-1, 1), Y.reshape(-1, 1), Z.reshape(-1, 1)))  
    RMat = R.from_euler('xyz', T, degrees = True)  # 创建一个欧拉旋转矩阵  
    XYZ = RMat.apply(XYZ)  # 应用旋转矩阵到数据点  
    return XYZ[:,0].reshape(SZ), XYZ[:,1].reshape(SZ), XYZ[:,2].reshape(SZ) 

# 贝塞尔函数插值生成花杆并绘制  
def dS(X, Y, Z):  
    # 找到Z中的最小值对应的索引  
    MN = np.where(Z == np.min(Z)); M = MN[0][0]; N = MN[1][0]  
  
    # 获取最小值点的坐标,并稍微提升z坐标值  
    x1 = X[M, N]; y1 = Y[M, N]; z1 = Z[M, N] + .03  
  
    # 设定贝塞尔曲线的三个控制点,其中第三个点通过旋转(x1, y1)得到  
    x = np.array([x1, 0, (x1*np.cos(np.pi/3) - y1*np.sin(np.pi/3))/3]).reshape((3,1))  
    y = np.array([y1, 0, (y1*np.cos(np.pi/3) + x1*np.sin(np.pi/3))/3]).reshape((3,1))  
    z = np.array([z1, -.7, -1.5]).reshape((3,1))  
  
    # 将控制点堆叠为一个3x3的数组P,并转置为3xN  
    P = np.hstack((x,y,z)).T  
  
    # 生成参数t,用于计算贝塞尔曲线上的点  
    t = (np.array(range(50)) + 1)/50  
  
    # 计算贝塞尔曲线的混合函数  
    c1 = np.array([1, 2, 1]).reshape(3,1)  
    c2 = np.power(t, np.array(range(3)).reshape(3,1))  
    c3 = np.power(1 - t, np.array(range(2, -1, -1)).reshape(3,1))  
  
    # 计算贝塞尔曲线上的点,并覆盖原P数组  
    P = (P @ (c1*c2*c3))  
  
    # 绘制贝塞尔曲线  
    ax.plot(P[0], P[1], P[2], color = '#58827E')  


# 创建figure窗口及axis坐标区域  
fig = plt.figure()  # 创建一个新的图形窗口  
ax = fig.add_subplot(111, projection='3d')  # 在图形窗口中添加一个3D子图  
  
# 绘制花束  
ax.plot_surface(rr*np.cos(tr), rr*np.sin(tr), hr + .35, rstride = 1, cstride = 1,  
                facecolors = cMpr(hr), antialiased = True, shade = False)  # 绘制一个3D表面表示花束  
  
# 通过变换rT获得新的坐标点U, V, W  
U, V, W = rT(rr*np.cos(tr), rr*np.sin(tr), hr + .35, [180/8, 0, 0]); V = V - .4  
  
# 循环旋转并绘制变换后的表面和花杆  
for i in range(5):  
    U, V, W = rT(U, V, W, [0, 0, 72])  # 旋转坐标点  
    ax.plot_surface(U, V, W - .1, rstride = 1, cstride = 1,  
                    facecolors = cMpr(hr), antialiased = True, shade = False)  # 绘制变换后的表面  
    dS(U, V, W - .1)  # 绘制花杆  
  
# 另一组花杆的绘制(假设与之前的类似,但使用不同的初始点和变换)  
u1, v1, w1 = rT(xb, yb, hb/2.5 + .32, [180/9, 0, 0])  
v1 = v1 - 1.35  
u2, v2, w2 = rT(u1, v1, w1, [0, 0, 36])  
u3, v3, w3 = rT(u1, v1, w1, [0, 0, 24])  
u4, v4, w4 = rT(u3, v3, w3, [0, 0, 24])  
  
for i in range(5):  
    u1, v1, w1 = rT(u1, v1, w1, [0, 0, 72])  
    u2, v2, w2 = rT(u2, v2, w2, [0, 0, 72])  
    u3, v3, w3 = rT(u3, v3, w3, [0, 0, 72])  
    u4, v4, w4 = rT(u4, v4, w4, [0, 0, 72])  
      
    # 绘制四组变换后的表面  
    ax.plot_surface(u1, v1, w1, rstride = 1, cstride = 1,  
                    facecolors = cMpb(hb), antialiased = True, shade = False)  
    ax.plot_surface(u2, v2, w2, rstride = 1, cstride = 1,  
                    facecolors = cMpb(hb), antialiased = True, shade = False)  
    ax.plot_surface(u3, v3, w3, rstride = 1, cstride = 1,  
                    facecolors = cMpb(hb), antialiased = True, shade = False)  
    ax.plot_surface(u4, v4, w4, rstride = 1, cstride = 1,  
                    facecolors = cMpb(hb), antialiased = True, shade = False)  
      
    # 绘制四组花杆  
    dS(u1, v1, w1)  
    dS(u2, v2, w2)  
    dS(u3, v3, w3)  
    dS(u4, v4, w4)  

# 设置3D坐标轴的位置  
# 参数分别为:(left, bottom, width, height),单位为相对于figure的宽和高的比例  
ax.set_position((-.215, -.3, 1.43, 1.43))  
  
# 设置坐标轴的长宽高比例  
# 这里设置x, y, z轴的比例为1:1:0.8  
ax.set_box_aspect((1, 1, .8))  
  
# 初始化3D坐标轴的视角  
# elev参数是仰角,以度为单位,表示从正上方向下看的角度  
# azim参数是方位角,以度为单位,表示从正北方向逆时针旋转的角度  
ax.view_init(elev=50, azim=2)  
  
# 关闭坐标轴  
# 这将隐藏坐标轴、刻度线和刻度标签  
ax.axis('off')  
  
# 显示图形  
plt.show()

 运行结果截图:

这束虚拟的紫色花束,它虽然没有真实鲜花的芬芳与触感,却是我们对母爱深沉而独特的赞美。紫色,象征着神秘、高贵与浪漫,正如母亲们在我们心中的形象,既深邃又充满爱意。

每一片紫色的花瓣,都代表着我对母爱的感激与敬意。它们层层叠加,如同母爱的厚重与深沉,无论岁月如何流转,母爱都如这紫色般永恒不变。

同时,紫色也寓意着神秘,如同母爱中那些我们未曾察觉的深情与付出。母亲们总是在默默地为我们付出,她们的辛劳与汗水,往往被我们忽视。但正是这些看似微不足道的付出,构成了母爱的伟大与厚重。

虽然,这束紫色花束不能亲手送到每一位母亲手中,却希望它能成为一个桥梁,连接我们与母亲们的心灵,让我们更加深刻地理解和感受母爱的伟大与无私。愿每一位母亲都能收到这份来自虚拟世界的真挚祝福,健康平安,自信美丽!!!

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值