From b2a9cc398360f9581b44d366b22d508cf287c58e Mon Sep 17 00:00:00 2001 From: Justyna Ilczuk Date: Wed, 26 Dec 2012 23:55:12 +0100 Subject: [PATCH] Woah it works! Now, I only want to write some communicates for user and make app more user friendly and more educational :D. --- rutherford.py | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 rutherford.py diff --git a/rutherford.py b/rutherford.py new file mode 100644 index 0000000..5870404 --- /dev/null +++ b/rutherford.py @@ -0,0 +1,182 @@ +from __future__ import division +from math import sqrt, ceil +import random, pygame, sys +import os +import json +from pygame.locals import * + +pygame.init() + +GRAY = ( 182, 182, 182) +VIOLET = (150, 100, 190) +RED = (150, 0, 0) +GREEN = (0, 150, 0) +BLUE = (30, 30, 180) +VERYLIGHT = (210, 210, 210) +BLACK = (0,0,0) +WHITE = (255, 255, 255) + +TIME_STEP = 0.01 + +K = 10000 + +X_SCREEN_BORDER = 1200 +Y_SCREEN_BORDER = 800 + +INITIAL_SPEED_X = 50 +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 + +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 + #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]) + + screen = Screen(window, colors, universe) + screen.draw_surface() + keep_running = True + while keep_running: + screen.draw_surface() + universe.update_positions() + 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 + elif event.key == K_DOWN: + INITIAL_Y += 10 + elif event.key == K_RIGHT: + INITIAL_SPEED_X += 20 + elif event.key == K_LEFT: + INITIAL_SPEED_X -= 20 + if(INITIAL_SPEED_X < 0): + INITIAL_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))) + + print "Pygame thread exited." + + + + +class Screen: + def __init__(self, window, colors, universe): + self.communicates = [] + self.communicates.append("Rutherford scattering") + self.window = window + self.universe = universe + self.colors = colors + self.color = WHITE + + def change_color(self): + self.color = random.choice(self.colors) + + def draw_universe(self): + self.draw_guide() + for particle in self.universe.particles: + self.draw_particle(particle) + + 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_guide(self): + pygame.draw.line(self.window, BLACK, (0, INITIAL_Y), (X_SCREEN_BORDER,INITIAL_Y), 2) + + 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) + pygame.display.flip() + + def print_text(self, text,xx,yy,color,text_size, screen): + font = pygame.font.SysFont(None,text_size) + ren = font.render(text,1,color) + screen.blit(ren, (xx,yy)) + + +class Vector2: + def __init__(self, x, y): + self.x = x + self.y = y + + + +class Particle: + def __init__(self, mass, position, old_position, charge, color): + self.mass = mass + self.position = position + self.old_position = old_position + self.acc = Vector2(0,0) + self.color = color + self.charge = charge + + +class Universe: + def __init__(self, particles): + self.particles = particles + print("Universe has just been created!") + + def update_accelerations(self): + for particle in self.particles: + particle.acc = Vector2(0,0) + for x in range(1, len(self.particles)): + accelerations = self.compute_acc(self.particles[x], self.particles[0]) + self.particles[x].acc = accelerations[0] + + def update_positions(self): + self.update_accelerations() + for particle in self.particles: + temporary_x = particle.position.x + temporary_y = particle.position.y + particle.position.x = 2 * particle.position.x - particle.old_position.x + particle.position.x += particle.acc.x * TIME_STEP * TIME_STEP + particle.position.y = 2 * particle.position.y - particle.old_position.y + particle.position.y += particle.acc.y * TIME_STEP * TIME_STEP + particle.old_position.x = temporary_x + particle.old_position.y = temporary_y + particle = self.limit_position(particle) + + 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) + 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 + return particle + + def compute_acc(self, particle1, particle2): + vertical_distance = particle1.position.y - particle2.position.y + horizontal_distance = particle1.position.x - particle2.position.x + distance = sqrt((vertical_distance)**2 + (horizontal_distance)**2) + force = particle1.charge * particle2.charge *K/distance**2 + acc1x = force/particle1.mass*horizontal_distance/distance + acc1y = force/particle1.mass*vertical_distance/distance + acc2x = -force/particle2.mass*horizontal_distance/distance + acc2y = -force/particle2.mass*vertical_distance/distance + return [Vector2(acc1x, acc1y), Vector2(acc2x, acc2y)] + + def add_particle(self, particle): + self.particles.append(particle) + + + + +if __name__ == '__main__': + main() \ No newline at end of file