[python趣味实战]----基于python代码实现浪漫爱心 დ

正文

01-效果演示

        下图是代码运行之后的爱心显示结果:

        下面的视频该爱心是动态效果,较为简洁,如果需要使用,可以进行完善,这里只是一个趣味实战,下面将对代码实现进行非常详细地描述:

浪漫爱心

02-代码实现

        下图是动态爱心代码实现,对所有代码进行详细解释如下:

         import random   // 导入Python中的random模块,用于生成随机数。
        from math import  sin, cos, pi, log   // 从math模块中导入sin、cos、pi和log函数,用于数学计算。
        from tkinter import *    // 从tkinter模块中导入所有内容,用于创建GUI界面。


        CANVAS_WIDTH = 640
        CANVAS_HEIGHT = 480
        CANVAS_CENTER_X = CANVAS_WIDTH / 2
        CANVAS_CENTER_Y = CANVAS_HEIGHT / 2

        // 定义了一些常量:CANVAS_WIDTH, CANVAS_HEIGHT, CANVAS_CENTER_X, CANVAS_CENTER_Y,用于定义画布的大小和中心位置。


        def center_window(root, width, height):  // 定义了一个函数center_window,接受三个参数root(窗口对象),width(窗口宽度),height(窗口高度)

        screenwidth = root.winfo_screenwidth():  // 使用winfo_screenwidth()方法获取屏幕的宽度,并将值赋给screenwidth变量

        screenheight = root.winfo_screenheight():  // 使用winfo_screenheight()方法获取屏幕的高度,并将值赋给screenheight变量

        size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2):  // 建一个字符串size,其中包括窗口的宽度和高度,以及窗口左上角的位置(居中显示计算)

        root.geometry(size):  // 使用geometry方法将窗口的大小和位置设置为size字符串中描述的值,从而将窗口居中显示在屏幕上


        def heart_function(t, shrink_ratio):  // 定义了一个心形函数heart_function,接受两个参数t(参数值)和shrink_ratio(缩小比率)

        x = 16 * (sin(t) ** 3):   // 计算心形曲线上点的x坐标,根据参数t的正弦值的三次方乘以16来计算

        y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t)):   // 计算心形曲线上点的y坐标,根据参数t的余弦值的线性组合来计算

        x *= shrink_ratio:   // 将计算出的x坐标乘以缩小比率shrink_ratio,用于对心形曲线进行缩放

        y *= shrink_ratio:   // 将计算出的y坐标乘以缩小比率shrink_ratio,用于对心形曲线进行缩放

        x += CANVAS_CENTER_X:   // 将x坐标移动到画布横向中心位置

        y += CANVAS_CENTER_Y:   // 将y坐标移动到画布纵向中心位置

        return int(x), int(y):   // 返回计算出的x和y坐标,使用int()函数将结果转换为整数类型。这样就得到了在画布上绘制心形图案所需要的坐标


         Heart类用于生成心形图案,初始化时会生成心形曲线上的点,并根据一定的规则进行扩散。生成心形图案后,可以根据指定的帧数进行渲染。下面逐个分析:

        def __init__(self, generate_frame=20):  // 定义了Heart类的初始化方法,接受一个参数generate_frame,默认值为20。在这个方法中进行了一些初始化操作

        self._points = set():   // 创建一个空集合_points,用于存储心形图案的点

        self._edge_diffusion_points = set():   // 创建一个空集合_edge_diffusion_points,用于存储心形图案的边缘扩散点

        self._center_diffusion_points = set():  // 创建一个空集合_center_diffusion_points,用于存储心形图案的中心扩散点

        self.all_points = {}:   // 创建一个空字典all_points,用于存储所有计算出的点

        self.build(2000):   // 调用build方法,传入参数2000,用于构建心形图案

        self.random_halo = 1000:   // 设置random_halo属性为1000,用于表示随机光晕的大小

        self.generate_frame = generate_frame:  // 将传入的generate_frame参数赋值给实例属性generate_frame,表示生成帧数

        for frame in range(generate_frame)::   // 遍历生成帧数的范围

        self.calc(frame):   // 调用calc方法,传入当前帧数frame作为参数,用于计算心形图案的点的位置。通过循环生成帧数次来完整绘制心形图案


        def build(self, number):  // 定义了Heart类中的build方法,接受一个参数number,用于生成指定数量的点

        for _ in range(number)::   // 遍历指定数量的次数

        t = random.uniform(0, 2 * pi):   // 生成一个随机的角度t,范围在0到2π之间

        x, y = heart_function(t, 11):   // 调用之前定义的heart_function函数,传入角度t和缩小比率11,计算得到心形曲线上的点的x和y坐标

        self._points.add((x, y)):   // 将计算出的点的坐标添加到_points集合中,第一个for循环结束后,_points集合中包含了心形曲线上的点

        for _x, _y in list(self._points)::   // 遍历_points集合中的所有点

        for _ in range(3)::   // 嵌套循环,执行3次

        self._edge_diffusion_points.add((x, y)):   // 将当前点加入_edge_diffusion_points集合中,实现边缘扩散

        point_list = list(self._points):   // 将_points集合转换为列表point_list

        for _ in range(4000)::   // 遍历4000次

        x, y = random.choice(point_list):   // 从point_list中随机选择一个点的坐标

        self._center_diffusion_points.add((x, y)):   // 将选定的点作为中心点,加入_center_diffusion_points集合中,实现中心扩散


         @staticmethod:  // 标记下面的calc_position方法为静态方法,即不需要实例化对象也可以直接调用该方法

        def calc_position(x, y, ratio):   // 定义了静态方法calc_position,接受三个参数x(x坐标)、y(y坐标)和ratio(比率)

        force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520):   // 计算力(force),根据点到画布中心的距离的0.520次方来计算

        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1):   // 计算x方向上的偏移量,根据比率、力和距离画布中心的偏移,再加上一个随机值

        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1):   // 计算y方向上的偏移量,同样根据比率、力和距离画布中心的偏移,再加上一个随机值

        return x - dx, y - dy:   // 返回新计算出的x和y坐标,通过减去对应的偏移量,实现点的位置更新

        这个静态方法calc_position用于根据点与画布中心的距离,以及指定的比率,计算点的新位置偏移量,从而实现点的移动。同时添加了一些随机性以增加点的变化


        def calc(self, generate_frame):  // 定义了Heart类中的calc方法,接受一个参数generate_frame,用于计算心形图案的点的位置

        ratio = 10:   // 设置比率为10

        halo_radius = int(4 + 6):   // 计算光晕的半径为10

        halo_number = int(3000 + 4000):   // 设置生成的光晕点的数量在7000左右

        all_points = []:   // 创建一个空列表all_points,用于存储所有计算出的点

        heart_halo_point = set():   // 创建一个空集合heart_halo_point,用于存储心形光晕点

        第一个循环用于生成心形光晕点,并添加到all_points列表中。随机选取角度t,计算心形曲线上的点坐标,加入heart_halo_point集合,加入随机偏移,选择大小,将点信息加入all_points列表

        第二个循环遍历心形曲线上的点,通过调用calc_position方法计算新的位置坐标,加入all_points列表

        第三个循环遍历边缘扩散点,同样通过调用calc_position方法计算新的位置坐标,加入all_points列表

        self.all_points[generate_frame] = all_points:   // 将生成的所有点信息存储在all_points字典中,以当前帧数generate_frame作为键值

        通过这些步骤,calc方法计算了心形图案上的点的新的位置,并将结果存储在all_points字典中


         def render(self, render_canvas, render_frame):  // 定义了Heart类中的render方法,接受两个参数render_canvas(用于绘制点的画布)和render_frame(当前帧数)

        for x, y, size in self.all_points[render_frame % self.generate_frame]::   // 遍历all_points字典中与当前帧数对应的点的信息

        alpha = int(((render_frame % self.generate_frame) / self.generate_frame) * 255):   // 计算当前帧数对总帧数取余再除以总帧数后的比例,并将其转换为alpha值(0-255范围)

        color = f"#{alpha:02X}0000":   // 根据计算得到的alpha值生成颜色字符串,格式为RGBA中的R=alpha,G=0,B=0,表示红色

        render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=color):   // 在绘制点的画布上创建一个矩形,以(x, y)为左上角坐标,(x+size, y+size)为右下角坐标,填充颜色为之前计算得到的红色


        root = Tk():  // 创建一个Tkinter应用程序的根窗口对象root

        root.title("浪漫爱心"):   // 设置窗口的标题为"浪漫爱心"

        center_window(root, CANVAS_WIDTH, CANVAS_HEIGHT):   // 调用center_window函数来将窗口居中显示在屏幕上,参数包括窗口对象root以及指定的画布宽度和高度

        canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH):   // 在窗口root上创建一个Canvas对象canvas,背景颜色为黑色,指定画布的高度和宽度为预定义的值CANVAS_HEIGHT和CANVAS_WIDTH

        canvas.pack():   // 将Canvas对象canvas放置到窗口中进行显示

        heart = Heart():   // 创建一个Heart类的实例对象heart,用于生成心形图案并进行后续的计算和渲染

        通过以上代码,创建了一个Tkinter窗口并在窗口中显示了一个黑色背景的Canvas画布,同时生成了一个Heart类的实例对象heart,准备后续使用该对象进行心形图案的绘制和动画效果展示。


        def draw(main, render_canvas, render_heart, render_frame=0):  // 定义了一个名为draw的函数,接受四个参数,分别为main(主窗口对象),render_canvas(用于绘制的画布对象),render_heart(Heart类实例对象),render_frame(当前帧数,默认为0)

        render_canvas.delete('all'):   // 在每次绘制之前,清空画布上的所有内容

        render_heart.render(render_canvas, render_frame):   // 调用Heart类中的render方法,将当前帧数和绘制的画布传入,用于绘制心形图案上的点

        main.after(300, draw, main, render_canvas, render_heart, render_frame + 1):   // 使用Tkinter中的after方法,设置300毫秒后执行draw函数,实现动画效果。同时将main窗口对象、render_canvas画布对象、render_heart对象以及更新后的render_frame作为参数传入

        Label(root, text="I Love You", bg="black", fg="#FF0000", font="Helvetic 20 bold").place(relx=.5, rely=.5, anchor=CENTER):   // 创建一个标签对象,显示文本"I Love You",设置背景颜色为黑色,前景色为红色,字体为Helvetica 20粗体,在窗口中居中显示

        root.mainloop():   // 进入Tkinter的主事件循环,等待响应用户事件,保持窗口显示

        通过以上代码,实现了一个动画效果,不断更新心形图案的点的位置并在画布上绘制,同时在窗口中显示 “I Love You” 的标签文本。整个程序会持续运行,直到用户关闭窗口。

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 / 2def center_window(root, width, height):screenwidth = root.winfo_screenwidth()  screenheight = root.winfo_screenheight()  size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)  root.geometry(size)  def heart_function(t, shrink_ratio):x = 16 * (sin(t) ** 3)y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))x *= shrink_ratioy *= shrink_ratiox += CANVAS_CENTER_Xy += CANVAS_CENTER_Yreturn int(x), int(y)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 = 1000self.generate_frame = generate_framefor 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, 11)self._points.add((x, y))for _x, _y in list(self._points):for _ in range(3):x, y = _x, _yself._edge_diffusion_points.add((x, y))point_list = list(self._points)for _ in range(4000):x, y = random.choice(point_list)self._center_diffusion_points.add((x, y))@staticmethoddef 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 - dydef calc(self, generate_frame):ratio = 10halo_radius = int(4 + 6)halo_number = int(3000 + 4000)all_points = []heart_halo_point = set()for _ in range(halo_number):t = random.uniform(0, 2 * pi)x, y = heart_function(t, 11.6)x, y = x, yif (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))self.all_points[generate_frame] = all_pointsdef render(self, render_canvas, render_frame):for x, y, size in self.all_points[render_frame % self.generate_frame]:alpha = int(((render_frame % self.generate_frame) / self.generate_frame) * 255)color = f"#{alpha:02X}0000"render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=color)root = Tk()
root.title("浪漫爱心")
center_window(root, CANVAS_WIDTH, CANVAS_HEIGHT)  canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
canvas.pack()heart = Heart()def draw(main, render_canvas, render_heart, render_frame=0):render_canvas.delete('all')render_heart.render(render_canvas, render_frame)main.after(300, draw, main, render_canvas, render_heart, render_frame + 1)draw(root, canvas, heart, 0)Label(root, text="I Love You", bg="black", fg="#FF0000", font="Helvetic 20 bold").place(relx=.5, rely=.5, anchor=CENTER)root.mainloop()

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

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

相关文章

Java数据结构-模拟实现ArrayList

MyArrayList顺序结构: 接口和MyArrayList重写接口 接口 接口中的方法是很多类通用的,所以可以写到接口中 public interface IList {public void add(int data) ;// 在 pos 位置新增元素public void add(int pos, int data);// 判定是否包含某个元素p…

踏上R语言之旅:解锁数据世界的神秘密码(三)

多元相关与回归分析及R使用 文章目录 多元相关与回归分析及R使用一.变量间的关系分析1.两变量线性相关系数的计算2.相关系数的假设检验 二.一元线性回归分析的R计算三、回归系数的假设检验总结 一.变量间的关系分析 变量间的关系及分析方法如下: 1.两变量线性相关…

LeetCode 727. 菱形

输入一个奇数 n n n,输出一个由 * 构成的 n n n阶实心菱形。 输入格式 一个奇数 n n n。 输出格式 输出一个由 * 构成的 n n n阶实心菱形。 具体格式参照输出样例。 数据范围 1 ≤ n ≤ 99 1≤n≤99 1≤n≤99 输入样例: 5输出样例: *…

JAVA的多态

在Java中,多态(Polymorphism)是面向对象编程的三大特性之一,它允许一个引用变量在运行时引用不同类的对象,并根据实际对象的类型来执行对应的方法。多态的存在增加了代码的灵活性和可扩展性。 多态的实现通常依赖于以下…

一文掌握python上下文管理器(with语句)

目录 一、上下文管理协议 二、with 语句 三、自定义上下文管理器 四、生成器上下文管理器 五、几个常用例子 1、自动关闭网络连接 2、临时更改目录 3、数据库事务管理 4、计时器上下文管理器 5、日志记录上下文管理器 6、资源锁定上下文管理器 7、临时修改环境变量…

windows远程访问树莓派ubuntu22.04 桌面 - NoMachine

通过nomachine 实现 windows 安装 nomachine 下载:链接:https://pan.baidu.com/s/10rGBREs-AnwRz7D7QbLQ1A?pwd8651 提取码:8651 安装:下一步 下一步 使用: 下一步 下一步 ubuntu 安装 nomachine服务 下载&#…

Java基础知识总结(81)

JUC容器 JUC基于非阻塞算法(Lock Free 无锁编程)提供了一组高并发的List、Set、Queue、Map容器。 JUC高并发容器是基于非阻塞算法实现的容器类,无锁编程算法主要通过CAS(Compare And Swap)volatile的组合实现&#x…

【C++程序员的自我修炼】string 库中常见的用法 (一)

唤起一天明月照我满怀冰雪浩荡百川流鲸饮未吞海 剑气已横秋 目录 string 库的简介 string 的一些小操作 构造函数的使用 拷贝构造的常规使用 指定拷贝内容的拷贝构造 拷贝字符串开始的前 n 个字符 用 n 个字符初始化 计算字符串的长度 string 的三种遍历方式 常规的for循环 op…

利用大型语言模型提升数字产品创新:提示,微调,检索增强生成和代理的应用

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

Linux基础part-6

一、Shell编程理论和运用 1、程序的编程风格和执行模式 编程风格(Programming Style) 过程式编程:以指令为中心,来进行写程序,数据服务于指令。(bash shell) C 以指令为中心,程序的逻辑由一系…

「笔试刷题」:字母收集

一、题目 描述 有一个 𝑛∗𝑚 的矩形方阵,每个格子上面写了一个小写字母。 小红站在矩形的左上角,她每次可以向右或者向下走,走到某个格子上就可以收集这个格子的字母。 小红非常喜欢 "love" 这四个字母。…

FFmpeg开发笔记(二十三)使用OBS Studio开启RTMP直播推流

OBS是一个开源的直播录制软件,英文全称叫做Open Broadcaster Software,广泛用于视频录制、实时直播等领域。OBS不但开源,而且跨平台,兼容Windows、Mac OS、Linux等操作系统。 OBS的官网是https://obsproject.com/,录制…

【报错处理】ib_write_bw执行遇到Couldn‘t listen to port 18515原因与解决办法?

要点 要点: ib默认使用18515端口 相关命令: netstat -tuln | grep 18515 ib_write_bw --help |grep port# server ib_write_bw --ib-devmlx5_1 --port88990 # client ib_write_bw --ib-devmlx5_0 1.1.1.1 --port88990现象: 根因&#xff…

为什么公共事业机构会偏爱 TiDB :TiDB 数据库在某省妇幼健康管理系统的应用

本文介绍了某省妇幼健康管理系统的建设和数据库架构优化的过程。原有的数据库架构使用了 StarRocks 作为分析层,但随着业务的发展,这套架构暴露出诸多痛点,不再适应妇幼业务的需求。为解决这些问题,该系统选择了将原有架构中的 St…

OBSERVER(观察者)-- 对象行为模式

意图: 定义对象间地一种一对多地依赖关系,当一个对象地状态发生改变时,所有对于依赖于它的对象都得到通知并被自动更新。 别名: 依赖(Dependents), 发布-订阅(Publish-Subsribe) 动机: 将一个系统分割成一系列相互协…

使用Python及R语言绘制简易数据分析报告

Pytohn实现 在python中有很多包可以实现绘制数据分析报告的功能,推荐两个较为方便的包:pandas-profiling 和 sweetviz 。 使用 pandas-profiling 包(功能全面) 这个包的个别依赖包与机器学习的 sklearn 包的依赖包存在版本冲突&a…

【C++中的模板】

和你有关,观后无感................................................................................................................. 目录 前言 一、【模板的引入和介绍】 1、泛型编程 2、【模板的介绍】 二、【 函数模板】 2.1【模函数板的介绍】 1.…

修改word文件的创作者方法有哪些?如何修改文档的作者 这两个方法你一定要知道

在数字化时代,文件创作者的信息往往嵌入在文件的元数据中,这些元数据包括创作者的姓名、创建日期以及其他相关信息。然而,有时候我们可能需要修改这些创作者信息,出于隐私保护、版权调整或者其他实际需求。那么,有没有…

【开源设计】京东慢SQL组件:sql-analysis

京东慢SQL组件:sql-analysis 一、背景二、源码简析三、总结 地址:https://github.com/jd-opensource/sql-analysis 一、背景 开发中,无疑会遇到慢SQL问题,而常见的处理思路都是等上线,然后由监控报警之后再去定位对应…

vue 前端读取Excel文件并解析

前端读取Excel文件并解析 前端如何解释Excel呢 平时项目中对于Excel的导入解析是很常见的功能,一般都是放在后端执行;但是也有特殊的情况,偶尔也有要求说前端执行解析,判空,校验等,最后组装成后端接口想要的…