在编程的世界里,Python 以其简洁易用和丰富的库而备受喜爱。用 Python 编写爱心代码,不仅能展现编程的魅力,还能传递温暖与爱意。今天就来分享几种创意 Python 爱心代码。
一、基于turtle
库绘制爱心
turtle
库是 Python 内置的图形库,能让我们轻松绘制各种图形,绘制爱心也不在话下。以下是代码示例:
import turtle
def draw_heart():
turtle.fillcolor('red')
turtle.begin_fill()
turtle.left(140)
turtle.forward(224)
turtle.circle(-112, 200)
turtle.left(120)
turtle.circle(-112, 200)
turtle.forward(224)
turtle.end_fill()
turtle.speed(1)
draw_heart()
turtle.done()
代码解析
- 导入库:
import turtle
导入turtle
库,为后续绘图操作做准备。 - 设置填充颜色和开始填充:
turtle.fillcolor('red')
将爱心的填充颜色设置为红色 ,turtle.begin_fill()
表示开始填充图形。 - 绘制爱心形状:
turtle.left(140)
让画笔向左旋转 140 度。turtle.forward(224)
向前绘制 224 个单位长度。turtle.circle(-112, 200)
绘制半径为 112(负号表示圆心在左侧 ),弧度为 200 度的圆弧,画出爱心左半部分。turtle.left(120)
再次调整方向。- 第二个
turtle.circle(-112, 200)
画出爱心右半部分。 turtle.forward(224)
移动回起点,完成爱心轮廓绘制。
- 结束填充和保持图形显示:
turtle.end_fill()
结束填充,turtle.done()
保持图形窗口显示,不会自动关闭。
二、利用matplotlib
库绘制基于数学公式的爱心
matplotlib
是一个强大的绘图库,我们可以结合爱心的数学公式来绘制出富有数学美感的爱心。
爱心的数学公式(参数方程)
\(\begin{cases} x = 16\sin^3t \\ y = 13\cos t - 5\cos(2t) - 2\cos(3t) - \cos(4t) \end{cases}\)
代码示例
import numpy as np
import matplotlib.pyplot as plt
# 生成参数t的值
t = np.linspace(0, 2*np.pi, 1000)
# 根据公式计算x和y的值
x = 16 * (np.sin(t)) ** 3
y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)
plt.plot(x, y, color='red') # 绘制线条,颜色设置为红色
plt.title('Mathematical Heart') # 设置标题
plt.xlabel('x') # 设置x轴标签
plt.ylabel('y') # 设置y轴标签
plt.axis('equal') # 设置坐标轴比例相等,使爱心不变形
plt.show() # 显示图形
代码解析
- 导入库:
import numpy as np
导入数值计算库numpy
,import matplotlib.pyplot as plt
导入绘图库matplotlib
的绘图模块。 - 生成参数值:
np.linspace(0, 2*np.pi, 1000)
生成在 0 到\(2\pi\)之间均匀分布的 1000 个数值,作为参数 t 的取值。 - 计算坐标值:根据爱心的数学公式,通过
numpy
的数组运算计算出对应的 x 和 y 坐标值。 - 绘图及设置:
plt.plot(x, y, color='red')
根据计算出的坐标绘制红色线条。plt.title('Mathematical Heart')
设置图形标题。plt.xlabel('x')
和plt.ylabel('y')
分别设置 x 轴和 y 轴的标签。plt.axis('equal')
确保坐标轴比例相等,让爱心形状不变形。plt.show()
显示绘制好的图形。
三、使用tkinter
库实现跳动的爱心动画
tkinter
是 Python 标准的 GUI(图形用户界面)库,能创建交互式应用程序。下面是一个跳动爱心动画的代码示例(代码较长,核心部分已注释):
from tkinter import *
import random
from math import sin, cos, pi, log
# 定义常量和全局变量
CANVAS_WIDTH = 640
CANVAS_HEIGHT = 640
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11.6
HEART_COLOR = "#e77c8e"
# 生成心形的函数
def heart_function(t, shrink_ratio=IMAGE_ENLARGE):
x = 16 * (sin(t) ** 3)
y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
x = x * shrink_ratio + CANVAS_CENTER_X
y = y * shrink_ratio + CANVAS_CENTER_Y
return int(x), int(y)
# 内部扩散函数
def scatter_inside(x, y, beta=0.15):
ratio_x = -beta * log(random.random())
ratio_y = -beta * log(random.random())
dx = ratio_x * (x - CANVAS_CENTER_X)
dy = ratio_y * (y - CANVAS_CENTER_Y)
return x + dx, y + dy
# 缩小函数
def shrink(x, y, ratio):
force = -1 / (ratio ** 2)
dx = force * (x - CANVAS_CENTER_X)
dy = force * (y - CANVAS_CENTER_Y)
return x + dx, y + dy
# 心形类
class Heart:
def __init__(self, generate_frame=20):
self._points = set()
self._edge_diffusion_points = set()
self._center_diffusion_points = set()
self.random_halo = 1000
self.generate_frame = generate_frame
self.build(2000)
def build(self, number):
for _ in range(number):
t = random.uniform(0, 2 * pi)
x, y = heart_function(t)
self._points.add((x, y))
if random.random() < 0.2:
self._edge_diffusion_points.add((x, y))
if random.random() < 0.1:
self._center_diffusion_points.add((x, y))
def calc_position(self, x, y, ratio):
force = 1 / (ratio ** 2)
dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)
return x + dx, y + dy
def calc(self, generate_frame):
ratio = 10 * (1 - generate_frame / 10 * pi)
halo_radius = int(4 + 6 * (1 + (1 - generate_frame / 10 * pi) ** 2))
halo_number = int(3000 + 4000 * abs((1 - generate_frame / 10 * pi) ** 2))
all_points = []
heart_halo_point = set()
for _ in range(halo_number):
t = random.uniform(0, 2 * pi)
x, y = heart_function(t, shrink_ratio=11.6)
x, y = shrink(x, y, halo_radius)
if (x, y) not in heart_halo_point:
heart_halo_point.add((x, y))
x += random.randint(-14, 14)
y += random.randint(-14, 14)
size = random.choice((1, 2, 2))
all_points.append((x, y, size))
for x, y in self._points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 3)
all_points.append((x, y, size))
for x, y in self._edge_diffusion_points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 2)
all_points.append((x, y, size))
for x, y in self._center_diffusion_points:
x, y = self.calc_position(x, y, ratio)
size = random.randint(1, 2)
all_points.append((x, y, size))
return all_points
def render(self, render_canvas, render_frame):
for x, y, size in self.calc(render_frame):
render_canvas.create_rectangle(x - size, y - size, x + size, y + size, fill=HEART_COLOR)
root = Tk()
root.title("跳动的爱心")
canvas = Canvas(root, bg="black", height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()
heart = Heart()
def draw():
heart.render(canvas, 10)
root.after(100, draw)
draw()
root.mainloop()
代码解析
- 导入库:导入
tkinter
库用于创建 GUI 界面,random
库用于生成随机数,sin
、cos
、pi
、log
用于数学计算。 - 定义常量和全局变量:设置画布的宽高、中心坐标、爱心放大倍数、颜色等参数。
- 定义函数:
heart_function
根据参数 t 计算爱心上点的坐标,并进行缩放和平移,使其位于画布中心。scatter_inside
对坐标进行内部扩散处理。shrink
对坐标进行缩小处理。
- 心形类定义:
__init__
初始化心形类的相关属性,并调用build
方法生成初始的点集。build
生成一定数量的心形点集,并根据随机条件划分出边缘扩散点和中心扩散点。calc_position
计算心形点在每一帧的新位置。calc
根据当前帧数计算心形点集的相关参数,包括光晕点集等,并整合所有点集。render
将计算得到的心形点集渲染到画布上,通过绘制矩形来表示点的位置和大小。
- 主程序部分:创建
Tk
窗口和画布,实例化Heart
类,定义draw
函数用于不断更新绘制爱心,通过root.after
实现定时调用draw
函数,形成动画效果,最后通过root.mainloop
启动 GUI 主循环。
这些爱心代码各有特色,你可以根据不同的场景和需求选择使用,也可以在此基础上进一步发挥创意,添加更多有趣的功能,比如让爱心变色、添加文字等。希望大家在编程中感受这份浪漫与乐趣!