我正在尝试编写一个程序,该程序有6个部分,一堆球彼此反弹。球没有做他们应该做的事情,而是彼此卡住了。有时它们会弹跳,而其他时候则不会。
我曾尝试过2D弹跳的多个公式,但这一次似乎实际上保持了动力。这是我以前修改过的模型,基本上是Wikipedia页面上2D碰撞的直接副本。那没有用,我从另一个stackoverflow答案中获得了当前模型,并产生了相同的结果。我以为我的物理学可能是对的,但是代码中的其他内容却将其弄乱了。我已经一遍又一遍地看了一下,但似乎还是找不到。任何帮助,将不胜感激。
from tkinter import *
import random
tk = Tk()
#canvas object
canv_width = 300
canv_height = 300
canvas1 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas2 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas3 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas4 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas5 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas6 = Canvas(tk, width = canv_width, height = canv_height, bg = 'black',highlightthickness=1, highlightbackground='white')
canvas1.grid(row=0,column=0)
canvas2.grid(row=0,column=1)
canvas3.grid(row=1,column=0)
canvas4.grid(row=1,column=1)
canvas5.grid(row=2,column=0)
canvas6.grid(row=2,column=1)
tk.title("BounceBox")
towns = {'1': canvas1, '2' : canvas2, '3': canvas3, '4' : canvas4, '5' : canvas5, '6': canvas6}
pops = {'1' : [], '2': [], '3': [], '4': [], '5': [], '6':[]}
def subtract(v1,v2):
x_comp = v1[0] - v2[0]
y_comp = v1[1] - v2[1]
return ((x_comp,y_comp))
def add(v1,v2):
x_comp = v1[0] + v2[0]
y_comp = v1[1] + v2[1]
return((x_comp,y_comp))
def dotproduct(v1,v2):
x_comp = v1[0] * v2[0]
y_comp = v1[1] * v2[1]
return(x_comp + y_comp)
def magnitude(v):
mag = (v[0]**2 + v[1]**2)**0.5
return mag
def mult_sv(s,v):
x_comp = s*v[0]
y_comp = s*v[1]
return((x_comp,y_comp))
def arctan(y,x):
try:
ans = math.atan(y/x)
if x >= 0 and y >= 0:
return ans
elif x <= 0 and y >= 0:
return ans + math.pi
elif x >= 0 and y <= 0:
return ans
else:
return ans - math.pi
except:
if y>0:
return math.pi
else:
return -math.pi
class Ball:
def __init__(self,radius,color,location,location_name):
self.location = location
self.location_name = location_name
self.radius = radius
ball_x = random.randint(0,canv_width - radius)
ball_y = random.randint(0,canv_height - radius)
self.pos = (ball_x,ball_y,ball_x + 2*self.radius, ball_y + 2*self.radius)
self.center = (self.pos[0] + self.radius, self.pos[1] + self.radius)
self.xspeed = random.randint(-1,1)
self.yspeed = random.randint(-1,1)
self.color = color
self.shape = self.location.create_oval(self.pos[0],self.pos[1],self.pos[2], self.pos[3], fill = self.color)
self.ball_update()
def check_collision(self):
for person in pops[self.location_name]:
center = person.center
distance = ((self.center[0] - person.center[0])**2 + (self.center[1] - person.center[1])**2)**0.5
if (distance <= 2*self.radius and person != self):
return (True,person)
return (False,None)
def ball_update(self):
#print(arctan(-1,1))
self.pos = self.location.coords(self.shape)
self.center = (self.pos[0] + self.radius, self.pos[1] + self.radius)
if (self.pos[0] <= 0 or self.pos[2] >= canv_width):
self.xspeed = -self.xspeed
if (self.pos[1] <= 0 or self.pos[3] >= canv_height):
self.yspeed = -self.yspeed
collision = self.check_collision()
if collision[0] == True:
v1 = (self.xspeed,self.yspeed)
v2 = (collision[1].xspeed, collision[1].yspeed)
dist = subtract(self.center,collision[1].center)
v12 = subtract(v1,v2)
dv = mult_sv(dotproduct(v12,dist)/ magnitude(dist)**2,dist)
self.xspeed -= dv[0]
self.yspeed -= dv[1]
collision[1].xspeed += dv[0]
collision[1].yspeed += dv[1]
self.location.move(self.shape, self.xspeed, self.yspeed)
self.center = (self.pos[0] + self.radius, self.pos[1] + self.radius)
tk.after(15,self.ball_update)
def create_populations():
for town in towns:
for pop in range(5):
person = Ball(10,'white',towns[town],town)
pops[town].append(person)
create_populations()
tk.mainloop()