猫史档案馆


【Python作品分享】爱心【作品秀】

用户:浩阳1zpZ浩阳1zpZ查看:4 回复:35 评论:4 创建时间:2022-11-18T13:16:36


【作品展示】

center_image

 

【作品介绍】

爱心代码

有需要的自取

 

【作品源代码】

# 晚喵月争辉,美梦陪你入睡
import random
from math import sin, cos, pi, log
from tkinter import *

CANVAS_WIDTH = 喵0  # 画布的宽
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第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 2下一页
浩阳1zpZ浩阳1zpZ

请大家多多捧场

点赞1


评论


望_庐山望_庐山

贴号不错()

点赞3


评论


浮生awa浮生awa

喵啊,我炖了半天了,删了又发删了又发,都没抢到第500000贴号,你随便发个python就占到了

点赞3


评论


倔强的扎古867倔强的扎古867

恭喜编程猫的帖子从此进入5打头的喵

点赞3


评论


水翎稞水翎稞

500000!!!

点赞0


评论


ficfrkficfrk

这光荣的贴号(

点赞0


评论


鼠饼鼠饼

在500000留下自己的足迹

点赞0


评论


茨i茨i

500000!!!

点赞0


评论


北京_地铁迷北京_地铁迷

500000!!

点赞0


评论


北京_地铁迷北京_地铁迷

2022年11月18日,编程猫迎来历史性的一幕,帖子突破500000个!

点赞1


评论


伴雪纷飞伴雪纷飞

500000!!!

点赞0


评论


AcetobacterAcetobacter

五十万帖!

点赞0


评论


慧音牢师慧音牢师

500000!!!

点赞0


评论


顧塰珼盜顧塰珼盜

帖主在吗?

点赞0


评论


边城过客边城过客

500000!!!

点赞0


评论


难起的名字难起的名字

随便改帖号看看有没有,结果真有!!!

点赞2


评论


荔枝冰激凌荔枝冰激凌

不错awa自己写的!?

点赞0


评论


艾博士艾博士

看这个https://qqqqqcy.github.io/heart_beat/

点赞0


评论


火菊火菊

500000!!!

点赞1


评论


名字送冷吖O名字送冷吖O

帖子标号从此进入5打头喵

点赞0


评论


云游box3der尖头叉子云游box3der尖头叉子

纪念一下()

点赞0


评论


萌新大佬萌新大佬

打卡

点赞0


评论


一个STUB用户_6923702一个STUB用户_6923702

纪念( 500000

点赞0


评论


清蒸鲈鱼清蒸鲈鱼

帖号几年5十万

点赞0


评论


e……e……

纪念+挖坟

点赞0


评论


AokenAoken

。。。

点赞0


评论


慧音牢师慧音牢师

【纪念】编程猫帖子从此迈入5打头的时/代

点赞0


评论


北京_地铁迷北京_地铁迷

打卡500000名(po)胜(lan)景区

点赞0


评论


无极玄天无极玄天

哇坟

点赞0


评论


面壁者罗辑LOGIC面壁者罗辑LOGIC

n    b

点赞0


评论