[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.两变量线性相关…

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

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

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

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

「笔试刷题」:字母收集

一、题目 描述 有一个 𝑛∗𝑚 的矩形方阵,每个格子上面写了一个小写字母。 小红站在矩形的左上角,她每次可以向右或者向下走,走到某个格子上就可以收集这个格子的字母。 小红非常喜欢 "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的导入解析是很常见的功能,一般都是放在后端执行;但是也有特殊的情况,偶尔也有要求说前端执行解析,判空,校验等,最后组装成后端接口想要的…

【大数据】利用 Apache Ranger 管理 Amazon EMR 中的数据权限

利用 Apache Ranger 管理 Amazon EMR 中的数据权限 1.需求背景简介2.系统方案架构图3.主要服务和组件简介3.1 Amazon EMR3.2 Simple Active Directory3.3 Apache Ranger 4.部署步骤4.1 部署 Simple AD 服务4.2 部署 Apache Ranger4.3 部署 Amazon EMR4.4 在 Amazon EMR 的主节点…

【数据结构】二叉树(带图详解)

文章目录 1.树的概念1.2 树的结构孩子表示法孩子兄弟表示法 1.3 相关概念 2.二叉树的概念及结构2.1 二叉树的概念2.2 数据结构中的二叉树-五种形态2.3 特殊的二叉树2.4 二叉树的存储结构顺序存储链式存储 2.5 二叉树的性质 3. 堆3.1 堆的定义3.2 堆的实现堆的结构堆的插入向上调…

java技术栈快速复习02_前端基础知识总结

前端基础 经典三件套: html(盒子)css(样式)JavaScript(js:让盒子动起来) html & css HTML全称:Hyper Text Markup Language(超文本标记语言),不是编程语…

不科学上网使用Hugging Face的Transformers库

参考 Program Synthesis with CodeGen — ROCm Blogs (amd.com) HF-Mirror - Huggingface 镜像站 https://huggingface.co/docs/transformers/v4.40.1/zh/installation#%E7%A6%BB%E7%BA%BF%E6%A8%A1%E5%BC%8F 准备 apt show rocm-libs -a pip install transformers python …

计算机网络—数据链路层

一、数据链路层的基本概念 结点:主机、路由器 链路:网络中两个结点之间的物理通道,链路的传输介质主要有双绞线、光纤和微波。分为有线链路、无线链路 数据链路:网络中两个结点之间的逻辑通道,把实现控制数据协议的…

ABAP 查找第二代增强

文章目录 ABAP 查找第二代增强第一种方法-根据包去查找第二种方法-通过MODX_FUNCTION_ACTIVE_CHECK重要的表MODSAP表TFDIR表TFTIT表 ABAP 查找第二代增强 第一种方法-根据包去查找 第二种方法-通过MODX_FUNCTION_ACTIVE_CHECK 第二代增强(基于函数模块的增强&…