[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.xdnf.cn/news/1409561.html

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

相关文章

判断字符串由几个单词组成(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int world 0;int i 0;char c 0;char string[81] { 0 };int num 0;//提示用户&#xff…

深入探索 C++ 中 string 的用法:从基础到实践

C String 用法详解 C中的 std::string 是一个非常强大且灵活的类&#xff0c;用于处理字符串。std::string 类是C标准库中的一部分&#xff0c;它提供了丰富的成员函数来执行各种字符串操作&#xff0c;如连接、比较、查找、替换等。在本篇博客中&#xff0c;我们将深入探索 s…

redis核心数据结构——跳表项目设计与实现(跳表结构介绍,节点类设计,随机层级函数)

跳表结构介绍。跳表是redis等知名软件的核心数据结构&#xff0c;其实现的前提是有序链表&#xff0c;思想的本质是在原有一串存储数据的链表中&#xff0c;间隔地抽出一半元素作为上一级链表&#xff0c;并将抽提出的元素和原先的位置相关联&#xff0c;这样重复下去直到最上层…

【考研数学】张宇「25版」跟「24版」的差距大吗?

其实差别不大&#xff01;要是进度比较快可以不跟着25更新&#xff0c;先跟着24的网课跟就可以了&#xff01; 身边真的很多130-140的大佬都是跟着张宇从头到尾&#xff0c;张宇老师的习题册非常适合基础扎实&#xff0c;想冲刺高分的考研党 我是属于基础不太好的&#xff0c…

Windows下面源码安装PostgreSQL

目录 一、环境&#xff1a; 二、安装MSYS2 三、安装PG 四、初始化数据库 五、启停数据库 六、调试PG 平时我们在LINUX下&#xff0c;使用源码安装PG的比较多&#xff0c;但在WINDOWS下安装&#xff0c;一般是使用二机制安装包来安装&#xff0c;能否使用源码来安装呢&…

【进收藏夹吃灰系列】算法学习指南

文章目录 [toc]分治算法 个人主页&#xff1a;丷从心 系列专栏&#xff1a;进收藏夹吃灰系列 分治算法 博客标题博客url【分治算法】【Python实现】Hanoi塔问题https://blog.csdn.net/from__2024_04_11/article/details/138093461?spm1001.2014.3001.5502

搜索引擎的设计与实现参考论文(论文 + 源码)

【免费】搜索引擎的设计与实现.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89249705?spm1001.2014.3001.5501 搜索引擎的设计与实现 摘要&#xff1a; 我们处在一个大数据的时代&#xff0c;伴随着网络信息资源的庞大&#xff0c;人们越来越多地注重怎样才能…

安装依赖报错前端安装某个依赖安装不上可能是node版本过高 升级或者降低node版本方式

安装依赖报错安装某个依赖安装不上可能是node版本过高 升级或者降低node版本方式 安装某个依赖安装不上 或者node版本过高 升级或者降低node版本 收藏关注一下吧 开发中难免总会需要切换node版本 需要的时候在找麻烦 主页 中还有更多干货分享

如何提高商务认知与情商口才(3篇)

如何提高商务认知与情商口才&#xff08;3篇&#xff09; **篇&#xff1a;提高商务认知 商务认知的提升是一个系统工程&#xff0c;需要我们不断地积累知识、理解市场和关注行业动态。以下是一些具体的方法&#xff1a; 持续学习&#xff1a;通过阅读商业书籍、参加行业研讨…

“猜你心里想的数” 小魔术揭秘

女儿展示了一个小魔术&#xff0c;如下 6 张写满数字的扑克&#xff1a; 让我心中默默选 1&#xff5e;60 中随意一个数字 x&#xff0c;然后她只依次拿这 6 张扑克问我 x 在不在里面&#xff0c;完事后她就知道 x 是多少。隐约记得哪里看到过这个魔术。 我拿过扑克仔细观察了…

Activiti工作流知识点图表总结

Acitivi是比较早的工作流引擎&#xff0c;后来居上者如Flowable或者Camunda&#xff0c;功能以及一些特性做了一些增强&#xff0c;这两个都是从Activiti的某个版本分离出来&#xff0c;独自发展。Flowable是由Activiti的主要开发者在离开Alfresco公司后创建的。Flowable项目是…

3.11设计模式——Visitor 访问者模式(行为型)

意图 表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的新操作。 结构 Visitor&#xff08;访问者&#xff09;为该对象结构中ConcreteElement&#xff08;具体元素&#xff09;的每一个类声明一个Visit操作&#xff0c;该操…

分类规则挖掘(二)

目录 三、决策树分类方法&#xff08;一&#xff09;决策树生成框架&#xff08;二&#xff09;ID3分类方法&#xff08;三&#xff09;决策树的剪枝&#xff08;四&#xff09;C4.5算法 三、决策树分类方法 决策树 (Decision Tree) 是从一组无次序、无规则&#xff0c;但有类别…

考研数学|李艳芳900比李林880难吗?值得做吗?

李艳芳老师比较有名的就是他的真题&#xff0c;900题还真是今年比较新的题集 目前&#xff0c;我看过900题的前两章&#xff0c;我觉得还是有一些亮点的&#xff1a; 900题第一章 与880第一章相比&#xff0c;两者各有千秋。880有种“一种题型一道题”&#xff08;”精做一题…

普冉PY32系列(十五) PY32F0系列的低功耗模式

目录 普冉PY32系列(一) PY32F0系列32位Cortex M0 MCU简介普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单普冉PY32系列(四) PY32F002A/003/030的时钟设置普冉PY32系列(五) 使用JLink RTT代替串口输出日志普冉PY32…

教育信息化对于教育新生态作用

现在往回观察我国的教育发展史&#xff0c;会发现教育的创新变革和社会的转型发展是一脉相承的。就当前&#xff0c;我们以人工智能技术为核心的新兴信息技术正在联合起来发力&#xff0c;正在引发科革命和技术产业的全面革命&#xff0c;这对于人类的生产生活&#xff0c;思维…

2024年五一杯高校数学建模竞赛(A题)|钢板切割问题 | 建模解析,小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;通过路径优化解决钢板切割问题。结合贪心算法&#xff0c;Floyd-Warshall等多元算法…

ESD管 AZ5825-01F国产替代型号ESDA05CPX

已经有很多客户选用雷卯的ESDA05CPX替代Amazing 的 AZ5825-01F&#xff0c; 客户可以获得更好的价格和更快的交期&#xff0c;主要应用于对5V供电和4.5V供电电流较大的Vbus线路插拔保护等。 雷卯ESDA05CPX优势&#xff1a; 带回扫 &#xff0c;钳位电压Vc 低&#xff0c;IPP为…

Windows11下Docker使用记录(四)

Docker使用记录&#xff08;四&#xff09; 1. container与host的文件传输2. container 与 Unity ROS setting 通讯3. container和wsl2或windows11我一直无法ping通 1. container与host的文件传输 从 container 复制文件至 host docker cp <container_name>:<file_p…

Springboot+Vue+小程序+基于微信小程序电影票网购系统

Java电影票购买管理系统&#xff0c;Maven管理工具&#xff0c;MyBatis数据库操作&#xff0c;idea平台开发&#xff0c;后台的前端为Vue&#xff0c;前台客户端为小程序&#xff0c;功能丰富&#xff0c;还有电影周边购买功能&#xff0c;请在最下方二维码处联系我即可&#x…