Woah it works!
Now, I only want to write some communicates for user and make app more user friendly and more educational :D.master
parent
f91d462270
commit
b2a9cc3983
|
@ -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()
|
Loading…
Reference in New Issue