前言 最近《点燃我温暖你》中李峋的爱心代码超级火,看着特别心动,这不,光棍节快到了,给兄弟们教学一波爱心代码,赶在双十一前表白,让这个双十一不在是孤单一个人!
涉及知识点
np.linspace()
用于返回指定区间等间隔的数组,例如np.linspace(0,2*np.pi)就是0到2π等间隔的数组
np.sin()
对中元素取正弦值
np.cos()
对中元素取余弦值
plt.plot()
是matplotlib.pyplot模块下的一个函数, 用于画图,它可以绘制点和线
plt.show()
展示图像
原理
原始的心形线的极坐标方程为r=a(1-cos)
与其对应的参数方程是:
x()=2r(sin-(sin2)/2)
y()= 2r(cos-(cos2)/2),(0<=<=2π)
代码
import numpy as np
import matplotlib.pyplot as plt
t=np.linspace(0,2*np.pi)#用于返回指定区间等间隔的数组
x=2*1*(np.cos(t)-np.cos(2*t)/2)
y=2*1*(np.sin(t)-np.sin(2*t)/2)
plt.plot(y,x,c='purple')#c=''控制颜色
plt.show()
执行结果
Python动态爱心代码
这个也是最还原的,代码过长,下面仅展示爱心的基础函数,需要的朋友可以去《点燃我温暖你》中李峋的同款爱心代码-Python文档类资源-CSDN文库下载,我设置的是免费下载
代码
x = 16 * (sin(t) ** 3)y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
执行结果
Python动态爱心代码
代码
# This is a sample Python script.
# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
# 国产热剧《点燃我温暖你》中李峋的爱心代码 复刻版
import random
from math import sin, cos, pi, log
from tkinter import *
CANVAS_WIDTH = 640 # 画布的宽
CANVAS_HEIGHT = 480 # 画布的高
CANVAS_CENTER_X = CANVAS_WIDTH / 2 # 画布中心的X轴坐标
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2 # 画布中心的Y轴坐标
IMAGE_ENLARGE = 11 # 放大比例
HEART_COLOR = "#FF359A" # 心的颜色,
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()
颜色代码色彩表
#000000 | #2F0000 | #600030 | #460046 | #28004D | |||||
#272727 | #4D0000 | #820041 | #5E005E | #3A006F | |||||
#3C3C3C | #600000 | #9F0050 | #750075 | #4B0091 | |||||
#4F4F4F | #750000 | #BF0060 | #930093 | #5B00AE | |||||
#5B5B5B | #930000 | #D9006C | #AE00AE | #6F00D2 | |||||
#6C6C6C | #AE0000 | #F00078 | #D200D2 | #8600FF | |||||
#7B7B7B | #CE0000 | #FF0080 | #E800E8 | #921AFF | |||||
#8E8E8E | #EA0000 | #FF359A | #FF00FF | #9F35FF | |||||
#9D9D9D | #FF0000 | #FF60AF | #FF44FF | #B15BFF | |||||
#ADADAD | #FF2D2D | #FF79BC | #FF77FF | #BE77FF | |||||
#BEBEBE | #FF5151 | #FF95CA | #FF8EFF | #CA8EFF | |||||
#d0d0d0<365> | #ff7575 | #ffaad5 | #ffa6ff | #d3a4ff | |||||
#E0E0E0 | #FF9797 | #FFC1E0 | #FFBFFF | #DCB5FF | |||||
#F0F0F0 | #FFB5B5 | #FFD9EC | #FFD0FF | #E6CAFF | |||||
#FCFCFC | #FFD2D2 | #FFECF5 | #FFE6FF | #F1E1FF | |||||
#FFFFFF | #FFECEC | #FFF7FB | #FFF7FF | #FAF4FF | |||||
#000079 | #000079 | #003E3E | #006030 | #006000 | |||||
#000093 | #003D79 | #005757 | #01814A | #007500 | |||||
#0000C6 | #004B97 | #007979 | #019858 | #009100 | |||||
#0000C6 | #005AB5 | #009393 | #01B468 | #00A600 | |||||
#0000E3 | #0066CC | #00AEAE | #02C874 | #00BB00 | |||||
#2828FF | #0072E3 | #00CACA | #02DF82 | #00DB00 | |||||
#4A4AFF | #0080FF | #00E3E3 | #02F78E | #00EC00 | |||||
#6A6AFF | #2894FF | #00FFFF | #1AFD9C | #28FF28 | |||||
#7D7DFF | #46A3FF | #4DFFFF | #4EFEB3 | #53FF53 | |||||
#9393FF | #66B3FF | #80FFFF | #7AFEC6 | #79FF79 | |||||
#AAAAFF | #84C1FF | #A6FFFF | #96FED1 | #93FF93 | |||||
#B9B9FF | #97CBFF | #BBFFFF | #ADFEDC | #A6FFA6 | |||||
#CECEFF | #ACD6FF | #CAFFFF | #C1FFE4 | #BBFFBB | |||||
#DDDDFF | #C4E1FF | #D9FFFF | #D7FFEE | #CEFFCE | |||||
#ECECFF | #D2E9FF | #ECFFFF | #E8FFF5 | #DFFFDF | |||||
#FBFBFF | #ECF5FF | #FDFFFF | #FBFFFD | #F0FFF0 | |||||
#467500 | #424200 | #5B4B00 | #844200 | #642100 | |||||
#548C00 | #5B5B00 | #796400 | #9F5000 | #842B00 | |||||
#64A600 | #737300 | #977C00 | #BB5E00 | #A23400 | |||||
#73BF00 | #8C8C00 | #AE8F00 | #D26900 | #BB3D00 | |||||
#82D900 | #A6A600 | #C6A300 | #EA7500 | #D94600 | |||||
#8CEA00 | #C4C400 | #D9B300 | #FF8000 | #F75000 | |||||
#9AFF02 | #E1E100 | #EAC100 | #FF9224 | #FF5809 | |||||
#A8FF24 | #F9F900 | #FFD306 | #FFA042 | #FF8040 | |||||
#B7FF4A | #FFFF37 | #FFDC35 | #FFAF60 | #FF8F59 | |||||
#C2FF68 | #FFFF6F | #FFE153 | #FFBB77 | #FF9D6F | |||||
#CCFF80 | #FFFF93 | #FFE66F | #FFC78E | #FFAD86 | |||||
#D3FF93 | #FFFFAA | #FFED97 | #FFD1A4 | #FFBD9D | |||||
#DEFFAC | #FFFFB9 | #FFF0AC | #FFDCB9 | #FFCBB3 | |||||
#E8FFC4 | #FFFFCE | #FFF4C1 | #FFE4CA | #FFDAC8 | |||||
#EFFFD7 | #FFFFDF | #FFF8D7 | #FFEEDD | #FFE6D9 | |||||
#F5FFE8 | #FFFFF4 | #FFFCEC | #FFFAF4 | #FFF3EE | |||||
#613030 | #616130 | #336666 | #484891 | #6C3365 | |||||
#743A3A | #707038 | #3D7878 | #5151A2 | #7E3D76 | |||||
#804040 | #808040 | #408080 | #5A5AAD | #8F4586 | |||||
#984B4B | #949449 | #4F9D9D | #7373B9 | #9F4D95 | |||||
#AD5A5A | #A5A552 | #5CADAD | #8080C0 | #AE57A4 | |||||
#B87070 | #AFAF61 | #6FB7B7 | #9999CC | #B766AD | |||||
#C48888 | #B9B973 | #81C0C0 | #A6A6D2 | #C07AB8 | |||||
#CF9E9E | #C2C287 | #95CACA | #B8B8DC | #CA8EC2 | |||||
#D9B3B3 | #CDCD9A | #A3D1D1 | #C7C7E2 | #D2A2CC | |||||
#E1C4C4 | #D6D6AD | #B3D9D9 | #D8D8EB | #DAB1D5 | |||||
#EBD6D6 | #DEDEBE | #C4E1E1 | #E6E6F2 | #E2C2DE | |||||
#F2E6E6 | #E8E8D0 | #D1E9E9 | #F3F3FA | #EBD3E8 |