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`)