我有一个Python Tkinter代码,其中涉及利用引力吸引移动粒子。我正在为粒子使用create_oval函数,并且代码可以正常工作,但我希望粒子留下痕迹(不创建多个椭圆形对象,这会使代码变慢很多)。
代码如下:
import tkinter as tk
import ctypes
from numpy import sin as _s, cos as _c, tan as _t, arctan2, radians
sin = lambda x: round(_s(x),14)
cos = lambda x: round(_c(x),14)
tan = lambda x: round(_t(x),14)
sqrDist = lambda x1, y1, x2, y2: ((x2-x1)**2 + (y2-y1)**2)
s_width,s_height = ctypes.windll.user32.GetSystemMetrics(0),ctypes.windll.user32.GetSystemMetrics(1)
colours = [(255, 0, 0),(255, 165, 0),(255, 255, 0),(0, 255, 0),(0, 0, 255),(75, 0, 130),(240, 130, 240)]
class Particle:
def __init__(self, x, y, ID, mass=1):
self.x, self.y = x, y
self.vx, self.vy = 0, 0
self.mass = mass
self.colour = colours[ID]
self.id = cv.create_oval(x-10, y-10, x+10, y+10, width = 0, fill = "#%02x%02x%02x" % self.colour)
def render(self):
x , y = self.x , self.y
cv.coords(self.id, [x-10,s_height-y+10,x+10,s_height-y-10])
def exertGravity():
for p1 in particles:
ax, ay = 0, 0
for p2 in particles:
if (p1 is p2):
continue
mag = (p2.mass)/sqrDist(p1.x, p1.y, p2.x, p2.y)
theta = arctan2(p2.y - p1.y, p2.x - p1.x)
ax += mag*cos(theta)
ay += mag*sin(theta)
p1.vx += ax
p1.vy += ay
esc = False
def escape(a):
global esc
esc = True
w = tk.Tk()
w.attributes("-fullscreen", True)
w.title('Particle Simulator')
w.geometry(str(s_width)+'x'+str(s_height)+"+0+0")
w.bind('<Escape>', escape)
cv = tk.Canvas(w, width=s_width, height=s_height)
cv.configure(background='black')
cv.pack()
p1 = Particle(960, 540, 0, 1)
p2 = Particle(960, 840, 1, 1)
p2.vx, p2.vy = -0.05,0
particles = [p1, p2]
while True:
if esc: break
exertGravity()
for p in particles:
p.render()
if p is p2:
p.x += p.vx
p.y += p.vy
cv.update()
w.destroy()