6 scale = 20 #Scale in pixels per angstrom
\r
8 mass = {"proton": 10**4, "electron":1} #Masses normalised to electron mass
\r
9 charge = {"proton":+1, "electron":-1} #Charges normalised to fundamental charge
\r
10 k = 10**-3 #Coulomb constant
\r
11 A = 10**-3 #Repulsion constant
\r
12 m = 6 #Inverse power for the repulsion law (Fr = A/r^m)
\r
15 def __init__(self, mass, charge, r):
\r
16 """Create a particle"""
\r
18 self.charge = charge
\r
24 """Do a single step"""
\r
27 for i in range(0,2):
\r
28 self.v[i] += self.f[i] / self.mass
\r
31 for i in range(0,2):
\r
32 self.r[i] += self.v[i]
\r
35 if self.r[0] <= 0 or self.r[0] >= 640:
\r
36 self.v[0] = -self.v[0]
\r
37 if self.r[1] <= 0 or self.r[1] >= 480:
\r
38 self.v[1] = -self.v[1]
\r
45 #sys.stdout.write("Position of " + str(self) + " is " + str(self.r) + "\n")
\r
50 for i in range(0,2):
\r
51 r[i] = b.r[i] - a.r[i]
\r
52 if r[0] == 0 and r[1] == 0:
\r
54 #if r[0] > 10**-10 or r[1] > 10**-10:
\r
59 distance = (r[0]**2 + r[1]**2)**(1/2)
\r
60 #sys.stderr.write(str(r[i] * (k * a.charge * b.charge)) + " ")
\r
61 #sys.stderr.write("Distance is " + str(distance) + "\n")
\r
62 for i in range(0,2):
\r
63 #Print out calculation
\r
64 #sys.stderr.write("f["+str(i)+"] -= " + str(r[i]) + " * (" + str(k) + " * " + str(a.charge) + " * " + str(b.charge) + " / (" + str(r[0]) + "^2 + " + str(r[1]) + "^2)^(3/2)\n")
\r
65 f[i] -= r[i] * (k * a.charge * b.charge / (distance**3))
\r
68 for i in range(0,2):
\r
69 f[i] -= r[i] * (A / ((distance)**(m+1)))
\r
71 # for i in range(0,2):
\r
72 # f[] -= r[i] * (A / ((distance-10)**(m+1)))
\r
75 def draw(self, window):
\r
77 if self.charge == 1:
\r
78 colour = pygame.Color(255,0,0,1)
\r
80 elif self.charge == -1:
\r
81 colour = pygame.Color(0,0,255,1)
\r
83 elif self.charge == 0:
\r
84 colour = pygame.Color(255,255,255,1)
\r
87 colour = pygame.Color(0,255,0,1)
\r
90 pygame.draw.circle(window,colour,[int(self.r[0] * scale), int(self.r[1] * scale)],size,0)
\r
91 #pygame.draw.line(window,colour,[int((self.r[0] - self.v[0]) / scale), int((self.r[1] - self.v[1]) / scale)], [int(self.r[0] / scale), int(self.r[1] / scale)])
\r
99 for i in range(0,0):
\r
100 self.particles.append(particle(mass["proton"],charge["proton"], universe.getRandomPosition()))
\r
101 self.particles.append(particle(mass["proton"] + 2*mass["electron"],charge["electron"],universe.getRandomPosition()))
\r
104 for a in self.particles:
\r
106 for b in self.particles:
\r
108 fAB = particle.calcForce(a,b)
\r
109 for i in range(0,2):
\r
114 def getRandomPosition():
\r
115 return [float(random.randint(0,640) / scale), float(random.randint(0,480) / scale)]
\r
117 def draw(self, window):
\r
118 for a in self.particles:
\r
121 if __name__ == "__main__":
\r
123 window = pygame.display.set_mode((640, 480))
\r
124 theUniverse = universe()
\r
132 #sys.stdout.write("Stepping...\n")
\r
135 window.fill(pygame.Color(0,0,0,0))
\r
136 theUniverse.draw(window)
\r
137 #Update draw events
\r
138 pygame.display.flip()
\r
140 #pygame.time.wait(1)
\r
142 for event in pygame.event.get():
\r
143 if event.type == pygame.QUIT:
\r
146 elif event.type == pygame.MOUSEBUTTONDOWN:
\r
147 mousestate = pygame.mouse.get_pressed()
\r
148 mousepos = pygame.mouse.get_pos()
\r
149 if mousestate[0] and mousestate[2] == False:
\r
150 theUniverse.particles.append(particle(mass["proton"],charge["proton"], [mousepos[0]/scale,mousepos[1]/scale]))
\r
151 elif mousestate[2] and mousestate[0] == False:
\r
152 theUniverse.particles.append(particle(mass["electron"],charge["electron"], [mousepos[0]/scale,mousepos[1]/scale]))
\r