How to make object bounce instead of just falling?

65 Views Asked by At

So, i tried to make a soft body object and as a starting point, I made a dot that falls down.

import numpy as np
import tkinter as tk
import math
root=tk.Tk()
root.geometry("700x350")
c=tk.Canvas(root, width=700, height=350, background="white")
c.pack()
class point():
    def __init__(self,pos,vel):
        self.position=np.array(pos)
        self.velocity=np.array(vel)
    def show(self):
        x=self.position[0]
        y=self.position[1]
        c.delete("all")
        c.create_oval(x-4,y-4,x+4,y+4,fill='black')
class runner():
    def __init__(self,points,force):
        self.ps=points
        self.grav=force
    def update(self,dt):
        for p in self.ps:
            p.velocity=p.velocity+np.array(self.grav)*dt
            p.position=p.position+p.velocity*dt
            p.show()
ps=[point([350,350//2],[-2,-2])]
x=runner(ps,[0,0.1])
while True:
    x.update(1)
    root.update()

How should i make it bounce on the ground? I understand collision detection in python, but i am not sure about collision resolution.

EDIT: I am asking for a way to work out the direction and force the ball should go in after hitting floor.

The closest I have come is with:

import numpy as np
import tkinter as tk
import math
import warnings
warnings.filterwarnings("error")
root=tk.Tk()
root.geometry("700x350")
c=tk.Canvas(root, width=700, height=350, background="white")
c.pack()
class Collision:
    def __init__(self, normal=[0.0, 0.0], depth=float('-inf')):
        self.normal = np.array(normal)
        self.depth = np.clip(depth,-1000,100)

def find_collision(position):
    return Collision([0.0, 1.0], -(300-position[1]))

class point():
    def __init__(self,pos,vel):
        self.position=np.array(pos)
        self.velocity=np.array(vel)
    def show(self):
        x=self.position[0]
        y=self.position[1]
        c.delete("all")
        c.create_oval(x-4,y-4,x+4,y+4,fill='black')
class runner():
    def __init__(self,points,force):
        self.ps=points
        self.grav=force
        self.friction=10
        self.elasticity=1
    def update(self,dt):
        for p in self.ps:
            p.velocity=p.velocity+np.array(self.grav)*dt
            c = find_collision(p.position)
            
            if c.depth>=0:
                try:
                    p.position += c.normal * c.depth
                    p.position=np.clip(p.position,-345,345)
                    vn = c.normal * np.dot(c.normal, p.velocity)
                    vt = p.velocity - vn
                    
                    vn = -self.elasticity * vn
                    
                    vt *= math.exp(-self.friction * dt)
                    
                    p.velocity = vn + vt
                    
                except RuntimeWarning:
                    print(c.normal,c.depth)
            p.position=p.position+p.velocity*dt
            p.show()
ps=[point([350,350//2],[0,0])]
x=runner(ps,[0,0.1])
while True:
    x.update(1)
    root.update()

0

There are 0 best solutions below