-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCollisionDetector.py
188 lines (140 loc) · 6.92 KB
/
CollisionDetector.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#-----------------------------------------------------------------------------------------#
#-------------------------------- Collision Detector ----------------------------------#
#-----------------------------------------------------------------------------------------#
# Date: 11/2021 #
# File: CollisionDetector.py #
#-----------------------------------------------------------------------------------------#
#-----------------------------------------------------------------------------------------#
# Packages #
#-----------------------------------------------------------------------------------------#
import csv
from types import DynamicClassAttribute
import CollisionDynamics
#-----------------------------------------------------------------------------------------#
# Global Variables #
#-----------------------------------------------------------------------------------------#
id_column = 0
mass_column = 1
q_column = 2
radius_column = 3
x_column = 4
y_column = 5
vx_column = 6
vy_column = 7
ax_column = 8
ay_column = 9
margin = 0.001
# max_cicles = 15
#-----------------------------------------------------------------------------------------#
# Code #
#-----------------------------------------------------------------------------------------#
def detect(Lista,Lista_out,N,delta):
for ide1 in range(N):
for ide2 in range(ide1): # Se compara hasta ide1 para evitar que se repita el análisis de choque
if abs(Lista[ide1].rx-Lista[ide2].rx)<delta and abs(Lista[ide1].ry-Lista[ide2].ry)<delta :
Lista_out.append([Lista[ide1].ID,Lista[ide2].ID])
# en vez de hacer un append se puede sustituir por la función que corrige las direcciones después del choque
# y se detiene una vez detecte al primer par de particulas colisionando
def collisions(data_block, xborder, yborder,max_cicles):
n_particles = len(data_block)
# last_data_block = data_block.copy()
velocity_unchanged = [True]*n_particles
# position_unfixed = [True]*n_particles
def pol(p1,p2):
x1 = float(data_block[p1][x_column])
y1 = float(data_block[p1][y_column])
x2 = float(data_block[p2][x_column])
y2 = float(data_block[p2][y_column])
dx = x2-x1
dy = y2-y1
d = (dx**2+dy**2)**(1/2)
if d < 1e-15:
d = 1e-15
# print(dx)
# print(dy)
# print(d)
unit_x = dx/d
unit_y = dy/d
return [d,unit_x,unit_y]
################################### Change velocities #####################################
###########################################################################################
for particle in range(n_particles):
radius = float(data_block[particle][radius_column])
x_max = xborder - radius
y_max = yborder - radius
x_min = radius
y_min = radius
prt_x = float(data_block[particle][x_column])
prt_y = float(data_block[particle][y_column])
if prt_x > x_max:
velocity_unchanged[particle] = False
data_block[particle][vx_column] = -float(data_block[particle][vx_column])
if prt_y > y_max:
velocity_unchanged[particle] = False
data_block[particle][vy_column] = -float(data_block[particle][vy_column])
if prt_x < x_min:
velocity_unchanged[particle] = False
data_block[particle][vx_column] = -float(data_block[particle][vx_column])
if prt_y < y_min:
velocity_unchanged[particle] = False
data_block[particle][vy_column] = -float(data_block[particle][vy_column])
if velocity_unchanged[particle]:
for i in range(n_particles):
if i != particle:
if velocity_unchanged[i]:
polar = pol(particle,i)
d = polar[0]
dmin = radius + float(data_block[i][radius_column])
if d < dmin:
particle_vx = data_block[particle][vx_column]
particle_vy = data_block[particle][vy_column]
data_block[particle][vx_column] = data_block[i][vx_column]
data_block[particle][vy_column] = data_block[i][vy_column]
data_block[i][vx_column] = particle_vx
data_block[i][vy_column] = particle_vy
velocity_unchanged[particle] = False
velocity_unchanged[i] = False
#################################### Change positions #####################################
###########################################################################################
for particle in range(n_particles):
radius = float(data_block[particle][radius_column])
x_max = xborder - radius
y_max = yborder - radius
x_min = radius
y_min = radius
check = True
checks = 0
while check:
check = False
checks += 1
for i in range(n_particles):
if i != particle:
polar = pol(particle,i)
d = polar[0]
unit_x = polar[1]
unit_y = polar[2]
dmin = radius + float(data_block[i][radius_column])
if d < dmin:
check = True
move_d = (dmin - d) + margin
move_x = -move_d*unit_x
move_y = -move_d*unit_y
data_block[particle][x_column] = float(data_block[particle][x_column]) + move_x
data_block[particle][y_column] = float(data_block[particle][y_column]) + move_y
prt_x = float(data_block[particle][x_column])
prt_y = float(data_block[particle][y_column])
if prt_x > x_max:
move = (prt_x - x_max) + margin
data_block[particle][x_column] = prt_x - move
if prt_y > y_max:
move = (prt_y - y_max) + margin
data_block[particle][y_column] = prt_y - move
if prt_x < x_min:
move = (x_min - prt_x) + margin
data_block[particle][x_column] = prt_x + move
if prt_y < y_min:
move = (y_min - prt_y) + margin
data_block[particle][y_column] = prt_y + move
if checks > max_cicles:
print('Collision loop exceeded for this particle')
break