|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 辉煌冕下 于 2024-5-28 15:04 编辑
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/2
IMAGE_ENLARGE=11
HEART_COLOR="#ff2121"
def heart_function(t,shrink_ratio:float=IMAGE_ENLARGE):
"""
“爱心函数生成器”
:paramshrink_ratio:放大比例
:paramt:参数
:renturn:坐标
"""
#基础函数
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:强度
:retuen:新坐标
"""
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)*22)**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_pionts.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):
ration=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,ration)
size=random.randint(1,3)
all_points.append((x,y,size))
#内容
for x,y in self._points:
x,y=self.calc_position(x,y,ration)
size=random.randint(1,3)
all_points.append((x,y,size))
for x,y in self._center_diffusion_points:
x,y=self.calc_position(x,y,ration)
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()
给你改好了:
- 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/2
- IMAGE_ENLARGE=11
- HEART_COLOR="#ff2121"
- def heart_function(t,shrink_ratio:float=IMAGE_ENLARGE):
- """
- “爱心函数生成器”
- :paramshrink_ratio:放大比例
- :paramt:参数
- :renturn:坐标
- """
- #基础函数
- 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:强度
- :retuen:新坐标
- """
- 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)*22)**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):
- ration=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,ration)
- size=random.randint(1,3)
- all_points.append((x,y,size))
- #内容
- for x,y in self._points:
- x,y=self.calc_position(x,y,ration)
- size=random.randint(1,3)
- all_points.append((x,y,size))
- for x,y in self._center_diffusion_points:
- x,y=self.calc_position(x,y,ration)
- 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.real, y.real, (x + size).real, (y + size).real, 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()
复制代码
|
|