弹跳2D球-Python

问题描述 投票:0回答:1

我正在尝试编写一个程序,该程序有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()
python tkinter simulation physics modeling
1个回答
1
投票
© www.soinside.com 2019 - 2024. All rights reserved.