-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
157 lines (122 loc) · 5.16 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 7 18:28:02 2020
@author: Paweł Bąk
"""
import turtle
import random
import time
# Box with boucing balls with theirs sizes, mass and gravity
# Screen settings
wn = turtle.Screen()
wn.bgcolor("black")
wn.title("Ball in the box")
wn.tracer(0, 0)
# Classes
class Box(turtle.Turtle):
""" Class that creates and customize the boundary box"""
def __init__(self, dye):
"""Set left bottom corner of the box and color"""
turtle.Turtle.__init__(self)
self.goto(-400,-400)
self.color(dye)
def create(self, a):
""" Creates the box. Variable "a" is a side length of the box"""
for b in range(4):
self.forward(a)
self.left(90)
self.hideturtle()
class Ball(turtle.Turtle):
""" Creates ball object with size (connected to mass), color, appear position and velocities"""
def __init__(self):
turtle.Turtle.__init__(self)
self.penup()
self.shape("circle")
colors = ["red", "blue", "yellow", "orange", "green", "purple"]
self.color(random.choice(colors))
def mass(self, mass):
"""Size of ball is connetced with mass. Trutlesize 1 has 20 pixels diameter, diameter value = mass"""
self.mass = mass
self.radius = self.mass/2
def position(self, x, y):
"""Appear position inside the box"""
self.x = x
self.y = y
self.goto(self.x, self.y)
def velocity(self, dx, dy):
"""Vertical and horizontal velocity. dx and dy means how many pixels ball can move in one loop step"""
self.dx = dx
self.dy = dy
class CollisionManager(object):
"""Check for collisions between the balls"""
def collision_without_mass(self):
"""Elastic collision without energy loss and mass
The balls are swapping velocities when the have contact"""
for i in range(0, len(balls)):
for j in range(i+1, len(balls)):
"""Check for a collision"""
if balls[i].distance(balls[j]) < balls[i].radius + balls[j].radius:
balls[i].dx, balls[j].dx = balls[j].dx, balls[i].dx
balls[i].dy, balls[j].dy = balls[j].dy, balls[i].dy
def collision_with_mass(self):
"""Elastic collision with mass, calculated from law of momentum conservation and kinetic enegry"""
for i in range(0, len(balls)):
for j in range(i+1, len(balls)):
"""Check for a collision and find new velocities """
if balls[i].distance(balls[j]) < balls[i].radius + balls[j].radius:
new_i_x = ((balls[i].mass * balls[i].dx + balls[j].mass * balls[j].dx +
balls[j].mass * cor *(balls[j].dx - balls[i].dx))/(balls[i].mass + balls[j].mass))
new_j_x = ((balls[i].mass * balls[i].dx + balls[j].mass * balls[j].dx +
balls[i].mass * cor *(balls[i].dx - balls[j].dx))/(balls[i].mass + balls[j].mass))
new_i_y = ((balls[i].mass * balls[i].dy + balls[j].mass * balls[j].dy +
balls[j].mass * cor *(balls[j].dy - balls[i].dy))/(balls[i].mass + balls[j].mass))
new_j_y = ((balls[i].mass * balls[i].dy + balls[j].mass * balls[j].dy +
balls[i].mass * cor *(balls[i].dy - balls[j].dy))/(balls[i].mass + balls[j].mass))
balls[i].dx = new_i_x
balls[j].dx = new_j_x
balls[i].dy = new_i_y
balls[j].dy = new_j_y
# Creating boundary box
box = Box("red")
box.create(800)
# Creating balls
balls = []
for objects in range(10):
balls.append(Ball())
# Range for balls appear position, it will be generated randomly
pos = range(-300,300,30)
# Balls properties
for ball in balls:
ball.position(random.choice(pos), random.choice(pos))
ball.velocity(random.randint(-1, 1), 2)
ball.mass(random.randint(10,60))
ball.turtlesize(ball.mass/20)
# Gravity value = 0.02 pixels will be substructed from veritcal velocity each loop step
# Check gravity = 0, it's fun!
gravity = 0
# Stickness coefficent. cor = 1 for elastic collision
cor = 1
# Main loop
while True:
wn.update()
time.sleep(0.002)
for ball in balls:
# Basic movement
ball.dy -= gravity
ball.sety(ball.ycor()+ ball.dy)
ball.setx(ball.xcor() + ball.dx)
# Check for contact y with boundary box
if ball.ycor() < -400 + ball.radius:
ball.dy *= -1
if ball.ycor() > 400 - ball.radius:
ball.dy *= -1
# Check for contact x with boundary box
if ball.xcor() > 400 - ball.radius:
ball.dx *= -1
if ball.xcor() < -400 + ball.radius:
ball.dx *= -1
"""Check for collisions between the balls"""
"""Avaliable = collision without mass, collision with mass"""
cm = CollisionManager()
cm.collision_with_mass()
wn.mainloop()