爱心跳动,粒子特效可循环

289 阅读1分钟

import random from math import sin, cos, pi, log import cv2 import numpy

width = 2572
height = 1440
center_x = width // 2
center_y = height // 2
heart_radius = 36

def heart_coord(t, radius): x = 16 * (sin(t) ** 3) y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

x = x * radius + center_x
y = y * radius + center_y
return int(x), int(y)

class Heart(object):

def __init__(self, img):
    self.img = img
    self.frame = img.copy()
    self.show_size = (int(width * 0.33), int(height * 0.33))
    self.edge_points = set()
    self.inside_points = set()
    self.outside_point = set()
    self.dots = 2500

    self.build()
    self.paint()

def build(self):
    dr = 0
    for m in range(9, 0, -1):
        do = log(m / 10) * -2
        dr += do
        n = int(self.dots / do)
        dt = 2 * pi / n
        t = 0
        for _ in range(n):
            tr = heart_radius - dr - random.uniform(0, do * 4)
            x, y = heart_coord(t, tr)
            self.edge_points.add((x, y, tr, t))
            t += dt
    t = 0
    dt = 2 * pi / self.dots
    for _ in range(self.dots):
        r = random.uniform(heart_radius, heart_radius + 8)
        x, y = heart_coord(t, r)
        self.outside_point.add((x, y, r, t))
        t += dt

def rectangle(self, center):
    b, g, r = (95, 47, 180)  # 颜色范围 (95, 47, 180) ~ (203, 169, 254)

    color = (b + random.randint(0, 60), g + random.randint(0, 60), r + random.randint(0, 120))
    cv2.rectangle(self.frame, center, (center[0] + 5, center[1] + 5), color, -1)

    color = (b + random.randint(60, 120), g + random.randint(60, 120), r + random.randint(80, 180))
    cv2.rectangle(self.frame, center, (center[0] + 3, center[1] + 3), color, -1)

def paint(self):
    self.frame = self.img.copy()
    for pt in self.edge_points | self.inside_points | self.outside_point:
        self.rectangle(pt[:2])
    self.frame = cv2.resize(self.frame, self.show_size)

def move(self, points, lower, upper):
    moved_points = set()
    for x, y, r, t in points:
        r2 = r + random.uniform(lower, upper)
        x2, y2 = heart_coord(t, r2)
        moved_points.add((x2, y2, r2, t))
    return moved_points

def dilate(self):
    self.edge_points = self.move(self.edge_points, 0, 0.8)
    self.inside_points = self.move(self.inside_points, 1, 2)
    self.outside_point = self.move(self.outside_point, -1, 1.1)
    self.paint()

if name == 'main': img = numpy.zeros((height, width, 3), numpy.uint8) Heart = Heart(img) cv2.imshow('heart', Heart.frame) cv2.waitKey(1000)

frames = []
for i in range(10):
    Heart.dilate()
    frames.append(Heart.frame)

frames = frames + frames[::-1]
while True:
    for image in frames:
        cv2.imshow('heart', image)
        if cv2.waitKey(60) in (32, 27, 13): 
            exit(`100000`)