-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparticle_interactions1.py
More file actions
107 lines (87 loc) · 3.49 KB
/
Copy pathparticle_interactions1.py
File metadata and controls
107 lines (87 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import pygame
import random
import math
# --- Ustawienia symulacji ---
WIDTH, HEIGHT = 800, 600
PARTICLE_COUNT = 150
PARTICLE_RADIUS = 3
PARTICLE_MASS = 1.0
GRAVITY_STRENGTH = 0.5 # Siła przyciągania między cząsteczkami
REPULSION_STRENGTH = 1000 # Siła odpychania przy kolizji
REPULSION_DISTANCE = 20 # Odległość, poniżej której występuje silne odpychanie
TIME_STEP = 0.1 # Krok czasowy symulacji (mniejsza wartość = większa stabilność)
BACKGROUND_COLOR = (0, 0, 0)
PARTICLE_COLOR = (255, 255, 255)
# --- Klasa Cząsteczki ---
class Particle:
def __init__(self, x, y):
self.x = x
self.y = y
self.vx = random.uniform(-1, 1) * 0.5 # Losowa prędkość początkowa
self.vy = random.uniform(-1, 1) * 0.5
self.radius = PARTICLE_RADIUS
self.mass = PARTICLE_MASS
def update(self):
# Aktualizacja pozycji na podstawie prędkości
self.x += self.vx * TIME_STEP
self.y += self.vy * TIME_STEP
def draw(self, screen):
# Rysowanie cząsteczki na ekranie
pygame.draw.circle(screen, PARTICLE_COLOR, (int(self.x), int(self.y)), self.radius)
# --- Inicjalizacja Pygame ---
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Symulacja Oddziaływań Cząsteczek")
clock = pygame.time.Clock()
# Tworzenie cząsteczek
particles = [Particle(random.randint(0, WIDTH), random.randint(0, HEIGHT)) for _ in range(PARTICLE_COUNT)]
# --- Główna pętla symulacji ---
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# --- Obliczanie sił i aktualizacja cząsteczek ---
for i in range(PARTICLE_COUNT):
p1 = particles[i]
# Obliczanie siły odpychania od ścian
if p1.x <= p1.radius or p1.x >= WIDTH - p1.radius:
p1.vx *= -1
if p1.y <= p1.radius or p1.y >= HEIGHT - p1.radius:
p1.vy *= -1
# Obliczanie oddziaływań między cząsteczkami
for j in range(i + 1, PARTICLE_COUNT):
p2 = particles[j]
dx = p2.x - p1.x
dy = p2.y - p1.y
distance = math.sqrt(dx**2 + dy**2)
# Zapobieganie błędom dzielenia przez zero i zbyt dużym siłom
if distance < 1:
distance = 1
# Siła odpychania (jeśli cząsteczki są blisko)
if distance < REPULSION_DISTANCE:
force = -REPULSION_STRENGTH / (distance**2)
# Dodajemy losowy element, żeby uniknąć symetrycznych wzorców
force += random.uniform(-0.1, 0.1)
# Siła przyciągania (jeśli cząsteczki są dalej)
else:
force = GRAVITY_STRENGTH / (distance**2)
# Obliczanie składowych siły (x i y)
fx = force * dx / distance
fy = force * dy / distance
# Zastosowanie siły na obu cząsteczkach (zasada akcji i reakcji)
p1.vx += fx / p1.mass * TIME_STEP
p1.vy += fy / p1.mass * TIME_STEP
p2.vx -= fx / p2.mass * TIME_STEP
p2.vy -= fy / p2.mass * TIME_STEP
# Aktualizacja pozycji wszystkich cząsteczek
for p in particles:
p.update()
# --- Rysowanie na ekranie ---
screen.fill(BACKGROUND_COLOR)
for p in particles:
p.draw(screen)
pygame.display.flip()
# Ograniczenie liczby klatek na sekundę
clock.tick(60)
pygame.quit()