I am in the middle of making a program that simulates chemical equilibrium. In theory, it is simple, it takes in initial concentrations of A (B is size of grid-A) and a probability of having A (B's probability is 1-A). Then it sets up an n by n grid with the initial conditions; randomly distributing each A. It then simulates what would occur to the concentration over time, but it disregards the initial conditions and calculates from a 1:0 ratio of A:B. I know why it does that, but I do not know how to make my program consider the initial conditions. My code is the following:
n = 100
A=3000
B=(n*n)-A
time = 25
probA = 70 #where probability of getting A is probA/prob
prob = 100
#Specifications
width = 5
height = width
x_position = width
y_position = height
#Functions
concA = []
concB = []
time1 = []
color1=[170,10,0]
color2=[0,170,170]
So far these are just empty lists and constants I need to run the program and display the data I want at the end.
def draw_initial(n):
countA_int=0
countB_int=0
for i in range(n):
for j in range(n):
y = y_position * j
x = x_position * i
r = randint(0,int(A+B))
if r<A:
clr=color1
countA_int +=1
else:
clr=color2
countB_int +=1
rect(x, y, width, height,*clr)
rect(x, y, width, height,*clr)
concA.append(100*countA_int/(n*n))
concB.append(100*countB_int/(n*n))
time1.append(0)
print('Initial concentrations:')
print('A = {} and B = {}'.format(concA[-1],concB[-1]))
wait_mouse_press()
clear()
So far I have made the initial grid. However, I know how to randomly distribute n amount of A in the grid. I just know how to make it so that roughly n percentage of the grid is A. Please instruct me here.
def start_reaction(n):
t = 1
while True:
countA_final = 0
countB_final = 0
for i in range(n):
for j in range(n):
y = y_position * j
x = x_position * i
r = randint(0,prob)
v=(-math.e**(-(1/math.e)*t))+1
if r <= v*probA:
clr = color1
countA_final += 1
else:
clr = color2
countB_final += 1
rect(x, y, width, height,*clr)
rect(x, y, width, height,*clr)
concA.append(100*countA_final/(n*n))
concB.append(100*countB_final/(n*n))
t += 1
time1.append(t-1)
print ('New round, time ={}'.format(t-1))
print('A = {}'.format(concA[-1]))
print('B = {}'.format(concB[-1]))
wait_mouse_press()
if t > time:
break
print(concA)
print(concB)
print(time1)
This next bit calculates how the grid looks for each iteration. It uses an odd formula to model the probability accurately. By the end it shows you this graph:
Clearly, there is an issue. At the very beginning, the data points jump instantly and then are modeled as they should be. The jump occurs because the second function doesn't know how the grid started and instead calculates a grid with only A at first and then does the iterations. I want my program to reach equilibrium from any given concentration, not only from 100% A. Can someone please help me?
Well, maybe it isn't of much interest for people, but I've managed to fix the issue. I won't bother explaining in detail but the issue had to do with the formula I used that modeled the increase or decrease in probability. I created another equation that would yield a variable that would shift the curve to the left in order to match the current concentration. If anyone wants the medialib file in order to run the code yourself, please write it in the comments. The code is the following:
from medialib import *
from random import randint # import randint() function
import matplotlib.pyplot as plt
import math
#Input variables
n = 100
A=1000 #must be between 0 and n*n
B=(n*n)-A
time = 25
probA = 50 #where probability of getting A is probA/prob
prob = 100
#Specifications
width = 5
height = width
x_position = width
y_position = height
#Functions
concA = []
concB = []
time1 = []
color2=[170,10,0]
color1=[0,170,170]
def draw_initial(n):
countA_int=0
countB_int=0
for i in range(n):
for j in range(n):
y = y_position * j
x = x_position * i
r = randint(0,int(A+B))
if r<A:
clr=color1
countA_int +=1
else:
clr=color2
countB_int +=1
rect(x, y, width, height,*clr)
rect(x, y, width, height,*clr)
concA.append(100*countA_int/(n*n))
concB.append(100*countB_int/(n*n))
time1.append(0)
print('Initial concentrations:')
print('A = {} and B = {}'.format(concA[-1],concB[-1]))
wait_mouse_press()
clear()
def start_reaction(n):
t = 1
while True:
countA_final = 0
countB_final = 0
if concA[-1]<probA:
l=math.e*math.log(1/(abs(1-(concA[-1]/probA))))
v=(-math.e**((-1/math.e)*(t+l)))+1
elif concA[-1]==probA:
l=math.e*math.log(1/(abs(1-((concA[-1]+0.1)/probA))))
v=(-math.e**((-1/math.e)*(t+l)))+1
elif concA[-1]>probA:
l=math.e*math.log(1/(abs(1-(concA[-1]/probA))))
v=(math.e**((-1/math.e)*(t+l)))+1
for i in range(n):
for j in range(n):
y = y_position * j
x = x_position * i
r = randint(0,prob)
if r < v*probA:
clr = color1
countA_final += 1
else:
clr = color2
countB_final += 1
rect(x, y, width, height,*clr)
rect(x, y, width, height,*clr)
concA.append(100*countA_final/(n*n))
concB.append(100*countB_final/(n*n))
t += 1
time1.append(t-1)
print ('New round, time ={}'.format(t-1))
print('A = {}'.format(concA[-1]))
print('B = {}'.format(concB[-1]))
wait_mouse_press()
if t > time:
break
print(concA)
print(concB)
print(time1)
draw_initial(n)
start_reaction(n)
wait_mouse_press()
import matplotlib.pyplot as plt
axes = plt.axes()
axes.set_ylim([0, 100])
plt.plot(time1,concA, label="Conc.A")
plt.plot(time1,concB, label="Conc.B")
plt.ylabel('% concentration')
plt.xlabel('time')
plt.show()
wait_mouse_press()
all_done() # always the last instruction of the program
That's the graph, see how the concentrations do not have to begin at 100:0 anymore.
Related
I am simulating 1D heat conduction using brownian motion in python. The question here is to track if the particle pass the inerface of the left or right cell. I have to count it somehow, could you please purpose solution or I should update code concept(rethink model).
Short desciption: Medium is consist of cell, in each cell it has own quantity of particles. The particles are moving from one cell to another. First and last cell has constant quantity of particle (in this case 500 and 0). Result gives the tempertaure profile along x. If we know the number of particles that are pass the interface of the cell (left or right) we might find Heat flux.
Edit: I've made counting of particle pass throught interface (from right or left). But in "theory" the value of Heat Flux should me constant. So, I gues there is the problem with my code(specified code excerpt). Could you please review it. Am I counting right?
Edit code:
import numpy as np
import matplotlib.pyplot as plt
def Cell_dist(a, dx):
res = [[] for i in range(N)]
for i in range(N):
for value in a:
if dx*i < value < dx*i+dx:
res[i].append(value)
return res
L = 0.2 # length of the medium
N = 10 # number of cells
dx = L/N # cell dimension
dt = 1 # time step
dur = 60 # duration
M = 20 # number of particles
ro = 8930 # density
k = 391 # thermal conductivity
C_p = 380 # specific heat capacity
T_0 = 100 # maintained temperature
T_r = 0 # reference temperature
DT = T_0 - T_r # characteristic temperature
a = k / ro / C_p # thermal diffusivity of the copper
dh_r = ro * C_p * dx * DT / M # refernce elementary enthalpy
c = (2*a*dt)**(1/2) # diffusion length
pos = [[] for i in range(N)] # creating cells
for time_step in range(dur):
M_plus = [[] for i in range(N-1)]
M_minus = [[] for i in range(N-1)]
flux = [0] * (N-1)
unirnd = np.random.uniform(0,dx, M).tolist() # uniform random distribution
pos[0] = unirnd # 1st cell BC
pos[-1] = [] # last cell BC at T_r = 0
curr_pos = sorted([x for sublist in pos for x in sublist]) # flatten list of particles (concatenation)
M_t = len(curr_pos) # number of particles at instant time step
pos_tmp = []
# Move each particle
for i in range(M_t):
normal_distr = np.random.default_rng().normal(0,1)
displacement = c*normal_distr
final_pos = curr_pos[i] + displacement
pos_tmp.append(final_pos)
#HERE is the question________________________
if normal_distr > 0:
for i in range(1,len(M_plus)-1):
if i*dx < final_pos < (i+1)*dx:
M_plus[i-1].append(1)
else:
for i in range(len(M_minus)):
if i*dx < final_pos < (i+1)*dx:
M_minus[i].append(1)
#END of the question________________________
for i in range(N-1):
flux[i] = (len(M_plus[i])-len(M_minus[i]))*dh_r/dt/1000
pos_new = Cell_dist(pos_tmp,dx)
pos_new[0] = unirnd
pos = pos_new
walker_number_in_cell = []
for i in range(N):
walker_number_in_cell.append(len(pos[i]))
T_n = []
for num in walker_number_in_cell:
T_n.append(T_r + num*dh_r/ro/C_p/dx)
# __________Plotting FLUX profile__________
x_a = [0]*(N-1)
for i in range(0, N-1):
x_a[i] = "{}".format(i+1)+"_{}".format(i+2)
plt.plot(x_a,flux[0:N-1],'-')
plt.xlabel('Interface')
plt.ylabel('Flux')
plt.show()
I am trying to write the Metropolis Algorithm for the Hardcore Model on the 2 dimensional lattice. The algorithm I wrote so far seems to work and is as follows:
-Pick a vertex of the 2-d lattice
-Toss a fair coin
-If the coin comes up heads and all neighbors of the vertex take value 0 then set the vertex to 1 otherwise to 0.
I try to animate the evolution of the lattice. Here is what I wrote so far:
The Algorithm to simulate works. The animation not as I want.
Here is the algorithm:
import random
from matplotlib import animation
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def Nachbarn(x0,x1,B): #test neighbours
if x1 +1 < len(B) and B[x0][x1+1] == 1 : #top
return True
elif x0 + 1 < len(B) and B[x0+1][x1] == 1 : #right
return True
elif x1 -1 >= 0 and B[x0][x1 -1] == 1 : #down
return True
elif x0 -1 >= 0 and B[x0-1][x1] == 1 : #left
return True
else:
return False
def Eckenwahl(B):
Länge = len(B)
x = random.choices(range(Länge),k=2) #choose a vertex
x0 = x[0]
x1 = x[1]
return x0,x1
def Münzwurf():
value = random.randint(0,1) #Toss a coin
return value
def MCMC(Array): #MCMC i-te Iteration
Ecke = Eckenwahl(Array)
if Münzwurf() == 1 and Nachbarn(Ecke[0],Ecke[1],Array) == False:
Array[Ecke[0]][Ecke[1]] = 1
else:
Array[Ecke[0]][Ecke[1]] = 0
return Array
Now, initialize the lattice:
N = 10 #Initialisierung of empty lattice
A = [[0] * N for i in range(N)]
If I apply the function MCMC on the array "A" a few times and start the animation with a non-empty lattice:
for i in range(5):
A = MCMC(A)
the animation seems to run, otherwise its stuck in the empty lattice and does not move forward. But I want to start it with an empty lattice. Here are two solutions that have these constraints so far:
Solution 1:
fig = plt.figure()
im = plt.imshow(A, animated = True)
def update_fig(*args):
global A
B = MCMC(A)
im.set_data(B)
return im
ani = animation.FuncAnimation(fig, update_fig, interval = 1)
plt.show()
Solution 2:
fps = 300
nSeconds = 10
fig = plt.figure( figsize=(8,8) )
a = A
im = plt.imshow(A)
def animate_func(i):
im.set_array(MCMC(A))
return [im]
anim = animation.FuncAnimation(fig, animate_func, frames = nSeconds *
fps,interval = 1000 / fps,)
The issue is, everything is ready. I want to start with a 2-d array/lattice that is full with 0`s called the empty configuration then, at time t=1 apply the function MCMC on the array, next display it in the animation and so on for t=2,3,...
Thanks for the help!
I am simulating sprinkler in 3D. In a previous question, I was helped to animate it in 2D (thank you #William Miller). I tried to use the same logic and implement it into 3D. In the update function, I get the following error:
'tuple' object is not callable
line 129 --> self.scat = self.ax.scatter(x,y,z, 'b.')
I looked at this answer when editing the code, which is why I used _offsets3d. I have looked through the Matplotlib documentation and tried to figure out why I'm getting a tuple object, but no success. I have also tried to simply use scatter on the given axes, but the kernel becomes unresponsive (even for 5 drops, 8 seconds, 50 frames). I'm not sure what to try next?
#Based on code by William Miller
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import animation
import numpy as np
from math import sin, cos
from mpl_toolkits.mplot3d import Axes3D
import random
#Parameters
rho = 1.225
c = 0.5
v0 = 50
g = 9.81
#Timing
fps = 20
tmax = 1*10
nframes = tmax*fps
time = np.linspace(0,tmax, nframes)
dt = time[1]-time[0]
#Waterdroplets
ndrops = 100
#Positioning
maxs = [0.0, 0.0, 0.0]
rmax = [0.0008, 0.0065] #range of radii of water droplets in m
finx = [] #record landing positions of the droplets to be used for analysis
finy = []
#Droplet sizing
theta = np.radians(np.random.normal(37, 8, 80))
phi = np.radians(np.random.normal(3, 1.07, 80))
radii = np.random.normal(0.004, 0.001, 80)
class drop:
def __init__(self,pos,vel,r):
self.pos = pos
self.vel = vel
self.r = r
class sprinkler:
def __init__(self):
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111, projection = '3d')
self.drops = [None]*ndrops # creates empty list of length ndrops
self.maxt = 0.0
theta = np.radians(np.random.normal(37, 8, 100))
phi = np.radians(np.random.normal(3, 1.07, 100))
radii = np.random.normal(0.004, 0.001, 100)
#Find the maximum flight time for each droplet
#and the maximum distance the droplets will travel
for i in range(len(phi)):
m = [drop([0.0, 0.0,0.1], [v0*cos(theta[i])*cos(phi[i]),
v0*cos(theta[i])*sin(theta[i]),
v0*sin(theta[i])],0.0008),
drop([0.0, 0.0,0.1], [v0*cos(theta[i])*cos(phi[i]),
v0*cos(theta[i])*sin(theta[i]),
v0*sin(theta[i])],0.0065)]
for d in m:
t = 0.0
coef = -0.5*c*np.pi*d.r**2*rho
mass = 4/3*np.pi*d.r**3*1000
while d.pos[2] > 0:
a = np.power(d.vel, 2) * coef * np.sign(d.vel)/mass
a[2] -= g
d.pos += (d.vel + a * dt) * dt
d.vel += a * dt
t += dt
if d.pos[2] > maxs[2]:
maxs[2] = d.pos[2]
if d.pos[1] > maxs[1]:
maxs[1] = d.pos[1]
if d.pos[0] > maxs[0]:
maxs[0] = d.pos[0]
if d.pos[2] < 0.0:
if t > self.maxt:
self.maxt = t
break
#print('Max time is:',maxt)
#print('Max positions are:', maxs)
#Create initial droplets
for ii in range(ndrops):
phiang = random.randint(0,len(phi)-1)
thetang = random.randint(0,len(theta)-1)
rad = random.randint(0,len(radii)-1)
self.drops[ii] = drop([0.0, 0.0, 0.1],
[v0*cos(theta[thetang])*cos(phi[phiang]),
v0*cos(theta[thetang])*sin(phi[phiang]),
v0*sin(theta[thetang])],
radii[random.randint(0,len(radii)-1)])
ani = animation.FuncAnimation(self.fig, self.update, init_func = self.setup,
interval = 200, frames = nframes)
ani.save('MySprinkler.mp4', fps = 20, extra_args=['-vcodec', 'libx264'])
plt.show()
def setup(self):
self.scat = self.ax.scatter([d.pos[0] for d in self.drops],
[d.pos[1] for d in self.drops],
[d.pos[2] for d in self.drops], 'b.')
self.ax.set_xlim(-1, 100)
self.ax.set_ylim(-1, 100)
self.ax.set_zlim(0, 50)
self.ax.set_xlabel('X Distance')
self.ax.set_ylabel('Y Distance')
self.ax.set_zlabel('Height')
return self.scat
def update(self, frame):
if time[frame] <(tmax-self.maxt*1.1):
self.create(ndrops)
self.step()
for d in self.drops:
x = d.pos[0]
y = d.pos[1]
z = d.pos[2]
self.scat = self.scat._offsets3d(x,y,z, 'b.')
return self.scat,
def create(self, i):
for l in range(i):
phiang = random.randint(0,len(phi)-1)
thetang = random.randint(0,len(theta)-1)
rad = random.randint(0,len(radii)-1)
self.drops.append(drop([0.0, 0.0, 0.0],
[v0*cos(theta[thetang])*cos(phi[phiang]),
v0*cos(theta[thetang])*sin(phi[phiang]),
v0*sin(theta[thetang])],
radii[rad]))
def step(self):
global finx, finy
for x in range(len(self.drops)):
coef = -0.5*c*np.pi*self.drops[x].r**2*rho
mass = 4/3*np.pi*self.drops[x].r**3*1000
a = np.power(self.drops[x].vel,2) * coef * np.sign(self.drops[x].vel)/mass
a[2] = a[2]-g
self.drops[x].pos += np.array(self.drops[x].vel)*dt +0.5*a*dt**2
self.drops[x].vel += a*dt
if self.drops[x].pos[2] < 0.0:
self.drops[x].pos[2] = 0.0
self.drops[x].vel = [0.0, 0.0, 0.0]
finx = np.append(finx, self.drops[x].pos[0])
finy = np.append(finy, self.drops[x].pos[1])
return self.drops, finx, finy,
sprinkler()
There seem to be 2 problems with the update function:
As the error message 'tuple' object is not callable indicates, _offsets3d(x,y,z, 'b.') is not a callable function. It is a tuple that holds x, y and z values.
These x,y,z can not be single values: they need to be in an array or list. So, you need to set all your drops at the same time.
I changed your update function to:
def update(self, frame):
if time[frame] <(tmax-self.maxt*1.1):
self.create(ndrops)
self.step()
x = np.array([d.pos[0] for d in self.drops])
y = np.array([d.pos[1] for d in self.drops])
z = np.array([d.pos[2] for d in self.drops])
self.scat._offsets3d = (x, y, z)
return self.scat,
giving a working animation (I ried with 5 drops) as illustrated below.
I didn't investigate the speed issues. A small thing you could change, is directly saving the drops into the format needed by _offsets3d, but that isn't the real culprit. What probably helps more is to use numpy's broadcasting for the calculations. Also note that you're constantly adding drops to your list getting larger and larger.
I have been trying to organise this program into loads of functions to make it more modular, but I have run into this error
Traceback (most recent call last):
File "N:\Starry\Planetary Orbits Ver 6.py", line 100
Forces(pos, Radii, Masses)# Computes all the forces between masses
File "N:\Starry\Planetary Orbits Ver 6.py", line 74, in Forces
r = pos-pos[:,newaxis] # all pairs of star-to-star vectors (Where r is the Relative Position Vector
TypeError: tuple indices must be integers, not tuple
I'm not sure I have set up the functions correctly, which is why im getting the error in the function.
Or is it because i've used a numpy function inside the Forces function?
from visual import *
from time import clock
from random import random
# Stars interacting gravitationally
# Program uses numpy arrays for high speed computations
Nstars = int(input("Number of stars: ")) # change this to have more or fewer stars
G = 6.7e-11 # Universal gravitational constant
# Typical values
Msun = 2E30
Rsun = 2E9
vsun = 0.8*sqrt(G*Msun/Rsun)
dt = 10.0 #Reprensents the change in time
Nsteps = 0
time = clock()
Nhits = 0
Stars = []
colors = [color.red, color.green, color.blue,
color.yellow, color.cyan, color.magenta]
PositionList = []
MomentumList = []
MassList = []
RadiusList = []
pos = ()
Radii = ()
Masses = ()
def Calculations(SpeedX, SpeedY, SpeedZ, x, y, z, Mass, Radius):
px = Mass*(SpeedX)
py = Mass*(SpeedY)
pz = Mass*(SpeedZ)
PositionList.append((x,y,z))
MomentumList.append((px,py,pz))
MassList.append(Mass)
RadiusList.append(Radius)
def StarCreation(Stars,x,y,z,Radius):
Stars = Stars+[sphere(pos=(x,y,z), radius=Radius, color=colors[i % 6],
make_trail=True, interval=10)]
def DataCollection():
x = input("Please enter The x position of the Star: ")
y = input("Please enter The y position of the Star: ")
z = input("Please enter The z position of the Star: ")
Radius = input("Please enter the Radius of the Star: ")
StarCreation(Stars,x,y,z,Radius)
Mass = input("Please enter the Mass of the Star: ")
SpeedX = input("Please enter the X speed of Star: ")
SpeedY = input("Please enter the Y speed of Star: ")
SpeedZ = input("Please enter the Z speed of Star: ")
Calculations(SpeedX, SpeedY, SpeedZ, x, y, z, Mass, Radius)
def Momenta(Momentum, Masses):
vcm = sum(Momentum)/sum(Masses) # velocity of center of mass
Momentum = Momentum-Masses*vcm # make total initial momentum equal zero
def ListToArray(PositionList, MomentumList, MassList, RadiusList):
pos = array(PositionList)
Momentum = array(MomentumList)
Masses = array(MassList)
Masses.shape = (Nstars,1) # Numeric Python: (1 by Nstars) vs. (Nstars by 1)
Radii = array(RadiusList)
Momenta(Momentum, Masses)
def Forces(pos, Radii, Masses):
# Compute all forces on all stars
r = pos-pos[:,newaxis] # all pairs of star-to-star vectors (Where r is the Relative Position Vector
for n in range(Nstars):
r[n,n] = 1e6 # otherwise the self-forces are infinite
rmag = sqrt(sum(square(r),-1)) # star-to-star scalar distances
hit = less_equal(rmag,Radii+Radii[:,newaxis])-identity(Nstars)
hitlist = sort(nonzero(hit.flat)[0]).tolist() # 1,2 encoded as 1*Nstars+2
F = G*Masses*Masses[:,newaxis]*r/rmag[:,:,newaxis]**3 # all force pairs
def UpdateMomentaPositions(Momentum, pos, Masses):
Momentum = Momentum+sum(F,1)*dt
pos = pos+(Momentum/Masses)*dt
def UpdateDisplay(pos):
Stars[i].pos = pos[i]
#~~~~~~~~~~~~~~~~~~~~~~~~~ Actual Proagram ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
for i in range(Nstars):
DataCollection()
ListToArray(PositionList, MomentumList, MassList, RadiusList)
while True:
rate(100) # No more than 100 loops per second on fast computers
Forces(pos, Radii, Masses)# Computes all the forces between masses
for n in range(NStars):
F[n,n] = 0 # No self forces
UpdateMomentaPositions(Momentum,pos,Mass) # Updates the Momentum and Positions of Stars
for i in range(Nstars):
UpdateDisplay(pos) # Updates the 3D displays position of Masses
What the problem is
I have to simulate balls in a box of 1 by 1.
i have to give the ball a random speed and a random angle it takes off in.
however when i plot the balls they go straight and have an asymptote at 0.25.
i double cheked my math but i cant find the problem?
My code
import numpy
import matplotlib.pyplot as plt
import math
import random
def rand_tuples(aantalballen): # here i make a function that randomly makes a list with lists in #
list_balls = [] # the list, every index is a ball with x_pos , y_pos , speed , rotation #
for i in range(aantalballen):
list_balls.append([0.25, 0.75,0.1* random.random(), 2* math.pi*random.random()])
return list_balls
def ball_step(list_balls, dt): # this function calculates the steps the balls takes #
x = list_balls[0]
y = list_balls[1]
vx = math.cos(list_balls[3]) * list_balls[2] # speed in the x direction #
vy = math.sin(list_balls[3]) * list_balls[2] # speed in the y direction #
dt = dt
x_pos = x + (vx * dt) # calculates the actual positions #
y_pos = y + (vy * dt)
if x_pos <= 0 or x_pos >= 1: # collision detection #
vx = -vx
if y_pos <= 0 or y_pos >= 1:
vy = -vy
return x_pos, y_pos, vx , vy # returns the new positions but the same speed so that they can be used again#
def move_ball(ballen, tijd, dt): # takes a list of balls, time they move and the time steps they take#
positions_balls = { } # hold my position in {0:{'x':[positions}, 'y':{...}}}
time_1 = 0
for i in range(len(ballen)) :
positions_balls[i] = None # make a key with empty value #
time_1 = 0
cordinates = {'x':[], 'y':[]} # make the dictionary where my values go into #
while time_1 < tijd:
bal = ball_step(ballen[i] , dt) # call bal step to calculate my x and y position #
ballen[i] = bal
cordinates['x'].append(bal[0])
cordinates['y'].append(bal[1])
time_1 += dt
if int(time_1) == tijd:
positions_balls[i] = cordinates # finally add the dictionary to my main dictionary #
print positions_balls
return positions_balls
dic = move_ball(rand_tuples(30), 3, 0.01)
plt.plot(dic[0]['x'], dic[0]['y'])
plt.show()
i do not have enough reputation to post a picture of the plot :(
ball_step() takes in (I think; comments are your friend) x, y, speed, rotation. It outputs x, y, speed x, speed y. That's assigned back to the original list.