summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustyna Ilczuk <justyna.ilczuk@gmail.com>2012-12-27 12:06:08 +0100
committerJustyna Ilczuk <justyna.ilczuk@gmail.com>2012-12-27 12:06:08 +0100
commita0b673afc1ca7f6ba684fdaaf4af8cff6bbf69c0 (patch)
treefd1a16145c12f256090e34f0fd447c19033f1597
parentb2a9cc398360f9581b44d366b22d508cf287c58e (diff)
downloadRutherford-a0b673afc1ca7f6ba684fdaaf4af8cff6bbf69c0.tar.gz
Rutherford-a0b673afc1ca7f6ba684fdaaf4af8cff6bbf69c0.tar.bz2
Rutherford-a0b673afc1ca7f6ba684fdaaf4af8cff6bbf69c0.zip
More user friendly. Instructions and so on ^^
-rw-r--r--rutherford.py152
1 files changed, 122 insertions, 30 deletions
diff --git a/rutherford.py b/rutherford.py
index 5870404..917e41e 100644
--- a/rutherford.py
+++ b/rutherford.py
@@ -1,5 +1,5 @@
from __future__ import division
-from math import sqrt, ceil
+from math import sqrt, ceil, atan, sin, cos
import random, pygame, sys
import os
import json
@@ -15,57 +15,68 @@ BLUE = (30, 30, 180)
VERYLIGHT = (210, 210, 210)
BLACK = (0,0,0)
WHITE = (255, 255, 255)
+GRAYISH = (210, 210, 255)
TIME_STEP = 0.01
-K = 10000
+K = 50000
X_SCREEN_BORDER = 1200
Y_SCREEN_BORDER = 800
-INITIAL_SPEED_X = 50
+INITIAL_SPEED_X = 200
INITIAL_SPEED_Y = 0
INITIAL_Y = 400
DEFAULT_OLD_X = 2 - INITIAL_SPEED_X*TIME_STEP
DEFAULT_OLD_Y = INITIAL_Y - INITIAL_SPEED_Y*TIME_STEP
+BEAM_WIDHT = 20
def main():
#create the screen
window = pygame.display.set_mode((1200, 800))
colors = [GRAY, VIOLET, RED, GREEN, BLUE, VERYLIGHT, BLACK]
- global INITIAL_SPEED_X
- global INITIAL_SPEED_Y
- global INITIAL_Y
+ settings = SimulationSettings(K, TIME_STEP, INITIAL_Y, INITIAL_SPEED_X, BEAM_WIDHT, colors)
#Initialize universe with some atoms
- atom1 = Particle(1000, Vector2(500,500), Vector2(500,500), 20, BLUE)
- atom2 = Particle(1, Vector2(2,400), Vector2(2-TIME_STEP*INITIAL_SPEED_X, INITIAL_Y- TIME_STEP*INITIAL_SPEED_Y), 1, RED)
- universe = Universe([atom1, atom2])
+ universe = Universe(settings)
screen = Screen(window, colors, universe)
screen.draw_surface()
keep_running = True
+ simulation_running = True
while keep_running:
- screen.draw_surface()
- universe.update_positions()
+ if(simulation_running):
+ screen.draw_surface()
+ universe.update_positions()
+ else:
+ screen.draw_static_surface()
+
for event in pygame.event.get():
if event.type == pygame.QUIT:
keep_running = False
elif event.type == pygame.KEYUP:
if event.key == K_UP :
- INITIAL_Y -= 10
+ universe.settings.initial_y -= 10
elif event.key == K_DOWN:
- INITIAL_Y += 10
+ universe.settings.initial_y += 10
elif event.key == K_RIGHT:
- INITIAL_SPEED_X += 20
+ universe.settings.speed_x += 20
elif event.key == K_LEFT:
- INITIAL_SPEED_X -= 20
- if(INITIAL_SPEED_X < 0):
- INITIAL_SPEED_X = 0
+ universe.settings.speed_x -= 20
+ if(universe.settings.speed_x < 0):
+ universe.settings.speed_x = 0
elif event.key == K_SPACE:
- universe.add_particle(Particle(1, Vector2(2,INITIAL_Y),
- Vector2(2-TIME_STEP*INITIAL_SPEED_X, INITIAL_Y- TIME_STEP*INITIAL_SPEED_Y),
- 1, random.choice(colors)))
+ universe.add_particle()
+ elif event.key == K_h:
+ if(universe.settings.show_instructions):
+ universe.settings.show_instructions = False
+ else:
+ universe.settings.show_instructions = True
+ elif event.key == K_RETURN:
+ if(simulation_running):
+ simulation_running = False
+ else:
+ simulation_running = True
print "Pygame thread exited."
@@ -89,18 +100,71 @@ class Screen:
for particle in self.universe.particles:
self.draw_particle(particle)
+ def draw_static_universe(self):
+ self.draw_guide()
+ for particle in self.universe.particles:
+ self.draw_particle(particle)
+ for x in range(1, len(self.universe.particles)):
+ self.draw_particle_vector(self.universe.particles[x])
+
def draw_particle(self, particle):
position = (int(ceil(particle.position.x)), int(ceil(particle.position.y)))
pygame.draw.circle(self.window, particle.color, position, 6+ int(particle.mass/100) )
+ def draw_particle_vector(self, particle):
+ factor = 20
+ arrow_head_x = 0.50
+ arrow_head_y = 0.30
+ start_position = (particle.position.x, particle.position.y)
+ end_position = (int((particle.position.x - particle.old_position.x)*factor +particle.position.x),
+ int((particle.position.y -particle.old_position.y)*factor + particle.position.y))
+
+ pygame.draw.aaline(self.window, BLUE, start_position, end_position, 4)
+ pygame.draw.circle(self.window, RED, end_position, 2)
def draw_guide(self):
- pygame.draw.line(self.window, BLACK, (0, INITIAL_Y), (X_SCREEN_BORDER,INITIAL_Y), 2)
+ y = self.universe.settings.initial_y
+ for x in range(0, 39, 2):
+ pygame.draw.aaline(self.window, BLACK, (X_SCREEN_BORDER*x/40, y), (X_SCREEN_BORDER*(x+1)/40, y), 4)
+
+
+
+ def draw_static_surface(self):
+ self.window.fill(GRAYISH)
+ self.draw_static_universe()
+ description_of_simulation_settings = self.prepare_settings_description(self.universe.settings)
+ for i, text in enumerate(self.communicates + description_of_simulation_settings):
+ self.print_text(text, 20, 20 + i*20, (0, 0, 0), 24, self.window)
+ if(self.universe.settings.show_instructions):
+ for i, text in enumerate(self.universe.settings.instructions):
+ self.print_text(text, 350, 20 + i*20, (0, 0, 0), 24, self.window)
+ pygame.display.flip()
+
+ def prepare_settings_description(self, settings):
+ description = []
+ line = "K = {0:d}".format(settings.K)
+ description.append(line)
+ line = "Position of the beam is {0:d}".format(settings.initial_y)
+ description.append(line)
+ line = "Initial speed of the beam is {0:d}".format(settings.speed_x)
+ description.append(line)
+ line = "Width of the beam is {0:d}".format(settings.beam_width)
+ description.append(line)
+ line = "Time step is set to {0:f}".format(settings.time_step)
+ description.append(line)
+ line = "Press H to show/hide instructions"
+ description.append(line)
+ return description
+
def draw_surface(self):
self.window.fill(self.color)
self.draw_universe()
- for i, text in enumerate(self.communicates):
- self.print_text(text, 20, 20 + i*20, (0, 0, 0), 30, self.window)
+ description_of_simulation_settings = self.prepare_settings_description(self.universe.settings)
+ for i, text in enumerate(self.communicates + description_of_simulation_settings):
+ self.print_text(text, 20, 20 + i*20, (0, 0, 0), 24, self.window)
+ if(self.universe.settings.show_instructions):
+ for i, text in enumerate(self.universe.settings.instructions):
+ self.print_text(text, 350, 20 + i*20, (0, 0, 0), 24, self.window)
pygame.display.flip()
def print_text(self, text,xx,yy,color,text_size, screen):
@@ -125,10 +189,30 @@ class Particle:
self.color = color
self.charge = charge
+class SimulationSettings:
+ def __init__(self, K, time_step, initial_y, speed_x, beam_width, colors):
+ self.K = K
+ self.time_step = time_step
+ self.initial_y = initial_y
+ self.speed_x = speed_x
+ self.beam_width = beam_width
+ self.colors = colors
+ self.show_instructions = True
+ self.instructions = [ "Instructions:",
+ "To change speed, use right and left arrow keys",
+ "To change position of the beam, use up and down arrow keys",
+ "To add particle, press space",
+ "To stop/restart simulation, press enter"]
+
class Universe:
- def __init__(self, particles):
- self.particles = particles
+ def __init__(self, settings):
+ self.settings = settings
+ atom1 = Particle(1000, Vector2(500,500), Vector2(500,500), 20, BLUE)
+ atom2 = Particle(1, Vector2(2,400), Vector2(2-TIME_STEP*INITIAL_SPEED_X,
+ INITIAL_Y- TIME_STEP*INITIAL_SPEED_Y), 1, RED)
+
+ self.particles = [atom1, atom2]
print("Universe has just been created!")
def update_accelerations(self):
@@ -154,11 +238,13 @@ class Universe:
def limit_position(self, particle):
if(particle.position.x > X_SCREEN_BORDER or particle.position.y > Y_SCREEN_BORDER or
particle.position.x < 0 or particle.position.y < 0):
- random_offset = random.randrange(-20, 20)
+ y = self.settings.initial_y
+ speed = self.settings.speed_x
+ random_offset = random.randrange(-self.settings.beam_width, self.settings.beam_width)
particle.position.x = 2
- particle.old_position.x = 2 - INITIAL_SPEED_X*TIME_STEP
- particle.position.y = INITIAL_Y + random_offset
- particle.old_position.y = INITIAL_Y - INITIAL_SPEED_Y*TIME_STEP + random_offset
+ particle.old_position.x = 2 - speed*self.settings.time_step
+ particle.position.y = y + random_offset
+ particle.old_position.y = y + random_offset
return particle
def compute_acc(self, particle1, particle2):
@@ -172,7 +258,13 @@ class Universe:
acc2y = -force/particle2.mass*vertical_distance/distance
return [Vector2(acc1x, acc1y), Vector2(acc2x, acc2y)]
- def add_particle(self, particle):
+ def add_particle(self):
+ y = self.settings.initial_y
+ speed = self.settings.speed_x
+ colors = self.settings.colors
+ random_offset = random.randrange(-self.settings.beam_width, self.settings.beam_width)
+ particle = Particle(1, Vector2(2, y + random_offset),
+ Vector2(2-self.settings.time_step*speed, y + random_offset), 1, random.choice(colors))
self.particles.append(particle)