Python编程 动态爱心

news2024/10/3 10:37:45

  • 作者简介:一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 

  •  座右铭:低头赶路,敬事如仪

  • 个人主页:网络豆的主页​​​​​​

目录

 前言

一.所用库

1.random简介

2.math 简介

3.tkinter库的简介

二.实际图

 三.代码部分

1.调用库

2.调整画布

3.爱心生成

4.随机内部扩散

5.抖动

6.自定义曲线函数,调整跳动周期

7.爱心类

8.@classmethod 装饰的类方法

四.全部源代码


 前言

本章将会使用Python实现动态的爱心效果

一.所用库

1.random简介

random库是用于产生并运用随机数的标准库。Python中的主要使用是让其掌握在程序中运用随机数的能力。

random常见随机函数有9个:seed()、random()、randint()、getrandbits()、randrange()uniform()、choice()、shuffle()、sample().


2.math 简介

math 库是 Python 提供的内置数学类函数库,因为复数类型常用于科学计算,一般计算并不常用,因此 math 库不支持复数类型,仅支持整数和浮点数运算。math 库一共提供了 4 个数学常数和 44 个函数。44 个函数分为 4 类,包括 16 个数值表示函数、8 个幂对数函数、16 个三角对数函数和 4 个高等特殊函数。


3.tkinter库的简介

Tkinter 是 Python 自带的图形界面库,库中包含众多图形界面控件,包括 Lable 标签、Button按钮、Radiobutton单选框、Checkbutton复选框、Entry文本框等。借助 Tkinter 库中的各种图形界面控件,我们就可以设计出实用的图形界面程序。


二.实际图


 三.代码部分

1.调用库

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

2.调整画布

CANVAS_WIDTH = 640#画布的宽
CANVAS_HEIGHT = 480#画布的宽
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR = "#FFC0CB" #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(p):

    return 2 * (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
    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
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR = "#FFC0CB" #ff2121


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)


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 / (((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):

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

  创作不易,求关注,点赞,收藏,谢谢~ 

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

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

相关文章

OKR之剑·实战篇06:OKR致胜法宝-氛围业绩双轮驱动(下)

作者:vivo 互联网平台产品研发团队 本文是《OKR 之剑》系列之实战第 6 篇—— 本文介绍团队营造氛围的方法与实践、在业绩方面的探索与输出,在两方面分别总结了一些经验分享给大家。 一、我们营造氛围的方法与实践 先说说氛围。组织氛围的提出者库尔…

10分钟学会数据库压力测试,你敢信?

目录 前言 查看数据库版本 下载驱动: 菜单路径 配置 Variable Name Bound to Pool模块配置 Connection pool configuration模块配置 Database Connection Configuration模块配置 菜单路径 Variable Name Bound to Pool 脚本结构 脚本(执行查询…

2.3 IS-IS认证

2.2.3 实验三:IS-IS认证 1. 实验目的  实现IS-IS接口认证 实现IS-IS区域认证实验IS-IS路由域认证2. 实验拓扑 IS-IS认证的实验拓扑如图2-6 图2-6:IS-IS认证 3. 实验步骤 配置IP地址(此处略…

让ChatGPT做当年的高考现代文阅读

最近ChatGPT火出天际,我突发奇想,如果用ChatGPT来做高考现代文阅读会怎样。 于是找到了当年非常火的一篇文章,叫《一种美味》,这个名字大家可能不太熟,但是提到其中一句话,你可能立马就想起来了。 「眼里…

一些NLP术语

一些NLP术语pre-training(预训练)fine-tuning(微调)下游任务Few-shot Learning(少样本学习)Prompt?(自然语言提示信息)二级标题三级标题pre-training(预训练&…

Redis第一讲

目录 一、Redis01 1.1 NoSql 1.1.1 NoSql介绍 1.1.2 NoSql起源 1.1.3 NoSql的使用 1.2 常见NoSql数据库介绍 1.3 Redis简介 1.3.1 Redis介绍 1.3.2 Redis数据结构的多样性 1.3.3 Redis应用场景 1.4 Redis安装、配置以及使用 1.4.1 Redis安装的两种方式 1.4.2 Redi…

字节软件测试岗:惨不忍睹的三面,幸好做足了准备,月薪15k,拿到offer

我今年25岁,专业是电子信息工程本科,19年年末的时候去面试,统一投了测试的岗位,软件硬件都有,那时候面试的两家公司都是做培训的,当初没啥钱,他们以面试为谎言再推荐去培训这点让我特别难受。 …

关于APP下载量提升的技巧

关于APP应用下载量提升,很多人都不是很了解。今天厦门巨神峰小编给大家说下关于APP下载量提升的几个技巧。 一、抓住流行趋势,提升APP下载量 1、利用社交媒体进行推广。社交媒体是当下最流行的推广手段,可以有效的将APP的消息传播到更多的用…

物联网对网页设计和开发的影响

当下从汽车、工业设备、家用电器到安全系统,越来越多的设备已经都连接到了互联网。与此同时,物联网在网页开发方面也有一些重大发展。因企业对于物联网应用需求不断增长,促使更多开发人员和设计人员从事物联网应用的开发和设计。下面我们将带…

Gotify消息推送系统搭建

昨天网友 sincoslong 提到了一个很好的建议: docker 注册表版本别选择 latest 选择具体版本号。 有的新版本,数据库、 php 各种依赖,都升级。小白如果选择最近更新的版本,估计写个 blog 都是记录如何失败的。 虽然有的人也会看…

STM32单片机超声波模块测距

OLED液晶接口电路图超声波模块接口电路图STM32单片机超声波模块测距程序源代码#include "sys.h"#define OLED_RST_Clr() PCout(13)0 //RST#define OLED_RST_Set() PCout(13)1 //RST#define OLED_RS_Clr() PBout(4)0 //DC#define OLED_RS_Set() PBout(4)1 //DC#define…

碰撞检测算法分类

包围形法粗糙检测, 包含以下两种类检测外接圆法轴对齐包围矩形, AABB 碰撞检测算法之包围形法分离轴精细检测 BOX vs PolygonOBBseparating Axis Theorem碰撞检测算法之分离轴定理GJKGJK(Gilbert–Johnson–Keerthi), 相比 SAT 算法&#xff…

Ae 入门系列之一:软件界面与工作流程

Adobe After Efftects(简称为 Ae )可以帮助用户高效且精确地创建无数引人注目的动态图形和震撼人心的视觉效果。利用与其他 Adobe 软件紧密集成和高度灵活的二维和三维合成,并且提供数百种预设的效果和动画,可为影视特效、产品广告…

如何使用COCO数据集,注意事项

COCO数据集可用来训练目标检测,分类,实例分割等。 下面简单说下如何使用这个数据集, 数据集下载可用如下的代码进行,以2017为例。 # Download the image data. cd ./images echo "Downloading MSCOCO train images ...&quo…

轨迹误差评估指标[APE/RPE]和EVO

轨迹误差评估指标[APE/RPE]和EVO1. ATE/APE2. RPE3. EVO3.1 评估指标3.2 使用3.2.1 轨迹可视化3.2.2 APE3.2.3 RPEReference: 高翔,张涛 《视觉SLAM十四讲》视觉SLAM基础:算法精度评价指标(ATE、RPE) 在实际工程中,我…

迁移案例实操:MySQL迁移到DM8由于有248张表存在datetime字段类型,使用dts迁移到达梦报不支持数据类型【附数据对比工具】

本文主要记录MySQL数据迁移到DM8上遇到MySQL源端表存在datetime数据类型时,并且包含datetime数据类型的表达上百张的的情况下,如何完成数据迁移的完整步骤。 1. 解决方法 将MySQL源端表的是datetime数据类型的字段修改为varchar(30)。 2. 处理步骤 &a…

JVM内存结构,Java内存模型,Java对象模型

一.整体方向JVM内存结构是和java虚拟机的运行时区域有关。Java内存模型和java并发编程有关。java对象模型和java对象在虚拟机中的表现形式有关。1.JVM内存结构堆:通过new或者其他指令创建的实例对象,会被垃圾回收。动态分配。虚拟机栈:基本数…

分布式之Paxos共识算法分析

写在前面 分布式共识是分布式系统中的重要内容,本文来一起看下,一种历史悠久(1998由兰伯特提出,并助其获得2003年图灵奖)的实现分布式共识的算法Paxos。Paxos主要分为两部分,Basic Paxos和Multi-Paxos,其中…

Web自动化测试——selenium的使用

⭐️前言⭐️ 本篇文章就进入了自动化测试的章节了,如果作为一名测试开发人员,非常需要掌握自动化测试的能力,因为它不仅能减少人力的消耗,还能提升测试的效率。 🍉欢迎点赞 👍 收藏 ⭐留言评论 &#x1f…

Python文件的操作处理,一看就会

在读取一个文件的内容之前,需要先打开这个文件。在Python程序中可以通过内置函数open()来打开一个文件程序中,并用相关的方法读或写文件文件中的内容以供程序的处理和使用,同时可以将文件看作Python中的一种数据类型。 open(filename, mode‘…