利用Python的Tkinter库,我们能够实现一个充满动感的爱心图形。该图形不仅包含了心形的绘制,还融入了扩散效果以及光环的渲染。通过代码,我们将展示如何创建一个爱心形状,并使其随着时间的推移呈现出扩散与变形的效果。
-
Tkinter库:Tkinter是Python的标准GUI(图形用户界面)库,它提供了丰富的组件和功能,用于创建各种图形界面。通过Tkinter,我们可以轻松地绘制图形、创建窗口以及实现交互效果。
-
心形的生成:心形可以通过数学公式来绘制。在二维坐标系中,心形曲线可以通过参数方程来表示,例如:
x(t)=16sin³(t)
y(t)=13cos(t)−5cos(2t)−2cos(3t)−cos(4t)
其中,t 是参数,范围通常为 0 到 2π。通过在Tkinter的画布上绘制这些点,就可以生成一个心形图形。
下面这段代码是一个基于 Python 和 Tkinter 模块实现的爱心动画程序。它通过数学公式生成爱心形状,并通过动态效果(如抖动、扩散、光环等)使其更具视觉吸引力:
1.模块导入
import random
from math import sin, cos, pi, log
from tkinter import *
-
random
:用于生成随机数,例如随机坐标或随机偏移量。 -
math
:导入sin
、cos
、pi
和log
函数,用于数学计算,特别是生成爱心形状的公式。 -
tkinter
:用于创建图形用户界面(GUI),包括窗口、画布(Canvas)等。
2.全局变量定义
CANVAS_WIDTH = 640
CANVAS_HEIGHT = 480
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR = "#EE94A7"
-
画布尺寸:
CANVAS_WIDTH
和CANVAS_HEIGHT
分别定义了画布的宽度和高度。 -
画布中心:
CANVAS_CENTER_X
和CANVAS_CENTER_Y
是画布中心的坐标,用于将爱心居中显示。 -
放大比例:
IMAGE_ENLARGE
定义了爱心的放大倍数。 -
颜色:
HEART_COLOR
是爱心的颜色,使用十六进制颜色代码表示粉红色。
3. 函数定义
3.1 爱心函数生成器
def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
x = 16 * (sin(t) ** 3)
y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
x *= shrink_ratio
y *= shrink_ratio
x += CANVAS_CENTER_X
y += CANVAS_CENTER_Y
return int(x), int(y)
-
功能:根据参数
t
和放大比例shrink_ratio
,生成爱心形状的坐标(x, y)
。 -
数学公式:使用参数方程生成爱心形状。
x
和y
的计算公式是基于三角函数的组合。 -
调整:将生成的坐标放大并移动到画布中心。
3.2 随机内部扩散
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
-
功能:对给定的坐标
(x, y)
进行随机偏移,模拟爱心内部的扩散效果。 -
偏移量:使用对数函数生成随机偏移量,
beta
控制扩散强度。
3.3 抖动效果
def shrink(x, y, ratio):
force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)
dx = ratio * force * (x - CANVAS_CENTER_X)
dy = ratio * force * (y - CANVAS_CENTER_Y)
return x - dx, y - dy
-
功能:根据距离画布中心的距离,对坐标
(x, y)
进行抖动效果。 -
衰减因子:
force
是一个与距离相关的衰减因子,用于控制抖动的强度。
3.4 动态曲线函数
def curve (p):
return 2*(2*sin(4*p))/(2*pi)
-
功能:生成一个正弦函数的值,用于控制动画的周期性变化(例如缩放比例或光环大小)。
4. 爱心类(Heart)
class Heart:
def__init__(self, generate_frame=20):
self._points =set()
self._edge_diffusion_points =set()
self._center_diffusion_points =set()
self.all_points ={}
self.build(2000)
self.random_halo =1000
self.generate_frame = generate_frame
for frame inrange(generate_frame):
self.calc(frame)
-
功能:
Heart
类用于生成和渲染爱心动画。 -
成员变量:
-
_points
:存储原始爱心的坐标。 -
_edge_diffusion_points
和_center_diffusion_points
:分别存储边缘扩散和中心扩散的坐标。 -
all_points
:存储每一帧的动态点坐标。 -
generate_frame
:动画的总帧数。
-
4.1 构建爱心
def build(self, number):
for _ in range(number):
t = random.uniform(0, 2 * pi)
x, y = heart_function(t)
self._points.add((x, y))
# 边缘扩散和中心扩散
for _x, _y in list(self._points):
for _ in range(3):
x, y = scatter_inside(_x, _y, 0.05)
self._edge_diffusion_points.add((x, y))
point_list = list(self._points)
for _ in range(4000):
x, y = random.choice(point_list)
x, y = scatter_inside(x, y, 0.17)
self._center_diffusion_points.add((x, y))
-
功能:生成原始爱心的坐标,并对其进行边缘扩散和中心扩散。
4.2 计算动态效果
def calc(self, generate_frame):
ratio = 10 * curve(generate_frame / 10 * pi)
halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
halo_number = int(3000 + 4000 * abs(curve(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))
self.all_points[generate_frame] = all_points
-
功能:计算每一帧的动态效果,包括光环、轮廓、边缘扩散和中心扩散。
4.3 渲染爱心
def render(self, render_canvas, render_frame):
for x, y, size in self.all_points[render_frame % self.generate_frame]:
render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)
-
功能:在画布上绘制每一帧的爱心动画。
5. 动画绘制函数
def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
render_canvas.delete('all')
render_heart.render(render_canvas, render_frame)
main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)
-
功能:通过
main.after
方法实现动画的循环绘制,每隔 160 毫秒绘制下一帧。
6. 主程序入口
if __name__ == '__main__':
root = Tk()
root.title("Missken")
canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()
heart = Heart()
draw(root, canvas, heart)
Label(root, text="Gozel", bg="black", fg="#FF99CC", font="Helvetic 20 bold").place(relx=.5, rely=.5, anchor=CENTER)
root.mainloop()
创建 Tkinter 窗口和画布,初始化 Heart
对象,并启动动画绘制。
效果: