Python制作爱心跳动代码,这就是程序员的烂漫吗

news2024/12/26 11:54:27

最近有个剧挺火的 就是那个程序员的剧,叫什么温暖你来着

咳咳,剧我没怎么看,但是吧,里面有个爱心代码,最近可是蛮火的,今天就用Python来尝试一下吧

怎么说呢,用这个表白也可以的,万一她也看这个剧呢,万一就成了呢 哈哈

这里插播一条粉丝福利,如果你在学习Python或者有计划学习Python,想在未来人工智能领域吃上一口饭的,可以点击这里获取最新的Python学习资料和学习路线规划(免费分享,记得关注)

图片

okok 话不多说,现在开始代码部分

代码

模块导入

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

画布的高和宽

有些数值咱自己也是可以调改的哈,这里我设置的高和宽是 480:640

CANVAS_WIDTH = 640  # 画布的宽
CANVAS_HEIGHT = 480  # 画布的高

x,y轴坐标

CANVAS_CENTER_X = CANVAS_WIDTH / 2  # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2  # 画布中心的Y轴坐标

放大比例

IMAGE_ENLARGE = 11  # 放大比例

心的颜色

这个自己看着改啊,想改啥色就改啥色

HEART_COLOR = "#ff8181"  # 心的颜色,芜湖我喜欢的粉色

函数生成器

if __name__ == '__main__':
root = Tk()  # 一个Tk
canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()
heart = Heart()  # 心
draw(root, canvas, heart)  # 开始画画~
    root.mainloop()

放大

# 放大
x *= shrink_ratio
y *= shrink_ratio

移到画布中央

基本操作,我要多发点文字哈哈,不然说我质量不行​​​​​​​

# 移到画布中央
    x += CANVAS_CENTER_X
    y += CANVAS_CENTER_Y
return int(x), int(y)

随机内部扩散​​​​​​​

def scatter_inside(x, y, beta=0.15):
"""
    随机内部扩散
    :param x: 原x
    :param y: 原y
    :param beta: 强度
    :return: 新坐标
    """
    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

抖动

这一步可关键了,咱做的就是跳动的爱心代码,so这一步重中之重​​​​​​​

def shrink(x, y, ratio):
"""
    抖动
    :param x: 原x
    :param y: 原y
    :param ratio: 比例
    :return: 新坐标
    """
    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

调整缩放比例

基本上都可以自己调改到自己喜欢的样子​​​​​​​

@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 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
    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()  # 心
    draw(root, canvas, heart)  # 开始画画~
    root.mainloop()

完整代码

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

CANVAS_WIDTH = 640  # 画布的宽
CANVAS_HEIGHT = 480  # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2  # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2  # 画布中心的Y轴坐标
IMAGE_ENLARGE = 11  # 放大比例
HEART_COLOR = "#ff2121"  # 心的颜色,这个是中国红


def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    """
    “爱心函数生成器”
    :param shrink_ratio: 放大比例
    :param t: 参数
    :return: 坐标
    """
    # 基础函数
    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)


def scatter_inside(x, y, beta=0.15):
    """
    随机内部扩散
    :param x: 原x
    :param y: 原y
    :param beta: 强度
    :return: 新坐标
    """
    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):
    """
    抖动
    :param x: 原x
    :param y: 原y
    :param ratio: 比例
    :return: 新坐标
    """
    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


def curve(p):
    """
    自定义曲线函数,调整跳动周期
    :param p: 参数
    :return: 正弦
    """
    # 可以尝试换其他的动态函数,达到更有力量的效果(贝塞尔?)
    return 2 * (2 * sin(4 * p)) / (2 * pi)


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))

    @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
    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()  # 心
    draw(root, canvas, heart)  # 开始画画~
    root.mainloop()

这里,我为您精心准备了一份全面的Python学习大礼包,完全免费分享给每一位渴望成长、希望突破自我现状却略感迷茫的朋友。无论您是编程新手还是希望深化技能的开发者,都欢迎加入我们的学习之旅,共同交流进步!

🌟 学习大礼包包含内容

Python全领域学习路线图:一目了然,指引您从基础到进阶,再到专业领域的每一步学习路径,明确各方向的核心知识点。

超百节Python精品视频课程:涵盖Python编程的必备基础知识、高效爬虫技术、以及深入的数据分析技能,让您技能全面升级。

实战案例集锦:精选超过100个实战项目案例,从理论到实践,让您在解决实际问题的过程中,深化理解,提升编程能力。

华为独家Python漫画教程:创新学习方式,以轻松幽默的漫画形式,让您随时随地,利用碎片时间也能高效学习Python。

互联网企业Python面试真题集:精选历年知名互联网企业面试真题,助您提前备战,面试准备更充分,职场晋升更顺利。

👉 立即领取方式:只需【点击这里】,即刻解锁您的Python学习新篇章!让我们携手并进,在编程的海洋里探索无限可能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2107759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络(运输层)

运输层概述 概念 进程之间的通信 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。 当网络的边缘部分中的两个主机使用网络的核心部分的功能进行端到端的通信时&a…

数量多怎么打印最便宜?

当您面临大量文件需要打印时,如何找到既经济又高效的打印解决方案成为关键。在众多打印服务中,琢贝云打印凭借其显著的价格优势和服务特色,成为众多用户的首选。 极致低价,成本更低 黑白打印超低价:提供的黑白打印服…

照明风暖浴霸语音控制芯片,智能声控开关芯片方案NRK3301

照明风暖浴霸通过特制的防水红外线热波管,与换气扇的巧妙组合,将浴室的取暖、红外线理疗、浴室换气、装饰等多种功能结合于一体的浴用小家电产品;为了提升产品的卖点,许多厂商都在尝试加各色各样的功能,某厂家加入了NR…

分销--分销人员管理系统架构文档

1. 概述 1.1 目的 本系统架构文档旨在描述分销人员管理系统的整体设计与结构,明确系统的功能模块、流程和技术实现,确保系统能够有效支持分销员的招募、管理及监督。 1.2 范围 本文档涵盖了分销员招募与管理。包括分销员列表、招募流程等。 2. 系统…

基于人工智能的垃圾分类图像识别系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 随着全球环境保护意识的增强,垃圾分类逐渐成为城市治理的关键任务之一。通过人工智能技术,尤其是图像识别系统…

Ascend C算子性能优化实用技巧03——搬运优化

Ascend C是CANN针对算子开发场景推出的编程语言,原生支持C和C标准规范,兼具开发效率和运行性能。使用Ascend C,开发者可以基于昇腾AI硬件,高效的实现自定义的创新算法。 目前已经有越来越多的开发者使用Ascend C,我们…

java控制流程

1.块作用域 用一对大括号括起来的就是一个块,块确定了变量的作用域。一个块可以嵌套在另一个块中。块外的变量在块内有效,而块内的变量在块外无效。 public class Main{public static void main(String[] args){int i1;{System.out.println("i&qu…

【2024】JAVA实现响应式编程Reactor具体API文档使用说明

目录💻 前言一、简介1、响应式编程概述背景知识什么是响应式编程具体概述应用场景:常用的库和框架 二、 Reactor实现响应式编程1、Flux 和 Mono介绍Flux:Mono:Flux 和 Mono 的区别:Flux 和 Mono 的关系: 2、常用API使用添加依赖2.1、生产流常用汇总 2.1.1、直接创建…

2024 高教社杯 数学建模国赛 (A题)深度剖析|“板凳龙” 闹元宵|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题! CS团队倾注了大量时间和心血,深入挖掘解…

设计模式之装饰器模式:让对象功能扩展更优雅的艺术

一、什么是装饰器模式 装饰器模式(Decorator Pattern)是一种结构型设计模式(Structural Pattern),它允许用户通过一种灵活的方式来动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比使用…

“Jmeter-InfluxDB-Grafana“常见错误有哪些如何解决?

常见错误: 1.网络不同,检查网络IP是否写对,端口号有没有放开(Centos7端口号命令),防火墙是否关闭 firewall-cmd --add-port3000/tcp --permanent firewall-cmd --add-port3000/udp --permanent firewall-…

中国剩余定理和扩展中国剩余定理(模板)

给你一元线性同余方程组&#xff0c;如下&#xff1a; 其中&#xff0c;当 , , ... , 两两互质的话就是中国剩余定理 &#xff0c; 不互质的话就是扩展中国剩余定理。 给出中国剩余定理的计算过程和扩展中国剩余定理的推理过程&#xff1a; #include<bits/stdc.h> us…

MT3516A-ASEMI三相整流桥MT3516A

编辑&#xff1a;ll MT3516A-ASEMI三相整流桥MT3516A 型号&#xff1a;MT3516A 品牌&#xff1a;ASEMI 封装&#xff1a;D-63 批号&#xff1a;2024 类型&#xff1a;三相整流桥 电流&#xff08;ID&#xff09;&#xff1a;35A 电压(VF)&#xff1a;1600V 安装方式&a…

C++开发基础之宏定义:入门、中级、高级用法示例解析

前言 在C开发中&#xff0c;宏定义是一种非常重要的预处理功能&#xff0c;能够简化代码、提高可读性、减少重复性工作。然而&#xff0c;宏的使用也存在一些潜在的风险&#xff0c;滥用宏可能导致代码难以调试和维护。在这篇博客中&#xff0c;我们将从入门、中级到高级&…

【数据库|第9期】SQL Server、Access和Sqlite 的字段别名详解

日期&#xff1a;2024年8月28日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

redis缓存的目的、场景、实现、一致性问题

文章目录 1、加缓存的目的&#xff08;作用&#xff09;&#xff1a;2、加缓存的场景&#xff1a;读多写少3、加不加缓存的标准&#xff1a;4、缓存的实现&#xff1a;5、缓存的实现方案&#xff1a;6、缓存的粒度问题7、缓存的一致性问题 专辑详情和声音详情属于并发量较高的数…

2024 高教社杯 数学建模国赛 (B题)深度剖析|生产过程中的决策问题|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题&#xff01; CS团队倾注了大量时间和心血&#xff0c;深入挖掘解…

入门数据结构JAVA DS——如何实现简易的单链表(用JAVA实现)

前言 链表&#xff08;Linked List&#xff09;是一种线性数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含两个部分&#xff1a;存储数据的部分和指向下一个节点的指针&#xff08;或引用&#xff09;。链表的结构使得它能够动态地增长和收缩&#xff0c;适合…

Python操作ES集群API

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

光明乳业以“轻”礼庆团圆!第七届莫斯利安保加利亚国际酸奶文化节圆满落幕

近日&#xff0c;第七届莫斯利安保加利亚国际酸奶文化节圆满落下帷幕。今年国际酸奶文化节恰逢中秋佳节之际&#xff0c;光明莫斯利安联合上海博物馆&#xff0c;以其缂丝馆藏《灵仙祝寿图》为灵感&#xff0c;推出了一系列联名限定产品和周边&#xff0c;寓意健康团圆长长久久…