超级简单又好看的Python绘制爱心,送给对象很不错哦~

本文介绍了使用Python和tkinter库在PyCharm中创建一个动态爱心图案的过程,包括代码结构、关键函数如heart_function、scatter_inside和shrink,以及如何实现随机扩散和跳动效果。
摘要由CSDN通过智能技术生成

点击直接免费获取全部源码

一、项目简介

这是一个用Python语言绘制的动态爱心图案,你❤动了吗?

编译器:PyCharm Community Edition

二、运行截图

在这里插入图片描述

在这里插入图片描述

三、代码思路

1、引入库文件random、math、tkinter

import random
from math import sin, cos, pi, log
from tkinter import \*

2、设置画布

CANVAS\_WIDTH = 800 #画布宽800
CANVAS\_HEIGHT = 600 #画布长600
CANVAS\_CENTER\_X = CANVAS\_WIDTH / 2
CANVAS\_CENTER\_Y = CANVAS\_HEIGHT / 2
IMAGE\_ENLARGE = 11
HEART\_COLOR = "#dc143c" #ff2121 #引号内为爱心的颜色

3、生成爱心

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)

4、随机扩散

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

5、抖动

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

6、定义曲线函数和跳动周期

def curve§:

return 5 \* (2 \* sin(4 \* p)) / (2 \* pi)

7、爱心的类

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 in range(generate\_frame):
        self.calc(frame)
 
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))

8、@classmethod 装饰类方法

@staticmethod
def calc_position(x, y, ratio):

    force = 1 / (((x - CANVAS\_CENTER\_X) \*\* 2 + (y - CANVAS\_CENTER\_Y) \*\* 2) \*\* 0.520)  # 魔法参数
 
    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 \* 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
 
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)
        
 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)


if \_\_name\_\_ == '\_\_main\_\_':
    root = Tk()  # 一个Tk
    root.title("dotcpp.com")
    canvas = Canvas(root, bg='black', height=CANVAS\_HEIGHT, width=CANVAS\_WIDTH)
    canvas.pack()
    heart = Heart()
    draw(root, canvas, heart)
    root.mainloop()

四、完整源码

点击直接免费获取全部源码

  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值