-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwave_simulate.py
More file actions
99 lines (86 loc) · 4.49 KB
/
wave_simulate.py
File metadata and controls
99 lines (86 loc) · 4.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
import pygame
import numpy as np
import time
class WaveSimulation:
def __init__(self):
# Define simulation parameters
self.WIDTH, self.HEIGHT = 800, 700
self.FPS = 60
self.NUM_POINTS_X = 50
self.NUM_POINTS_Y = 50
self.SPACING_X = self.WIDTH // self.NUM_POINTS_X
self.SPACING_Y = self.HEIGHT // self.NUM_POINTS_Y
self.DAMPING = 0.9999999999 # Increase damping
self.WAVE_SPEED = 0.0091 # Increase wave speed
self.WAVE_HEIGHT_THRESHOLD = 0.01
# Initialize Pygame
pygame.init()
self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT))
self.clock = pygame.time.Clock()
# Create grid of points
self.points = np.zeros((self.NUM_POINTS_X, self.NUM_POINTS_Y, 2))
self.velocities = np.zeros((self.NUM_POINTS_X, self.NUM_POINTS_Y, 2))
self.wave_heights = np.zeros((self.NUM_POINTS_X, self.NUM_POINTS_Y))
# Add an initial disturbance to the wave
self.wave_heights[self.NUM_POINTS_X // 2, self.NUM_POINTS_Y // 2] = 1
# Rest of the code remains the same...
def run(self):
# Main loop
running = True
while True:
self.screen.fill((0, 0, 0))
# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
running = not running
elif event.key == pygame.K_r:
self.wave_heights = np.zeros((self.NUM_POINTS_X, self.NUM_POINTS_Y))
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
i = x // self.SPACING_X
j = y // self.SPACING_Y
self.wave_heights[i, j] = 50 # Increase the disturbance created by the mouse click
# Update wave simulation
if running:
for i in range(1, self.NUM_POINTS_X - 1):
for j in range(1, self.NUM_POINTS_Y - 1):
self.velocities[i, j, 0] += (self.wave_heights[i + 1, j] + self.wave_heights[i - 1, j] +
self.wave_heights[i, j + 1] + self.wave_heights[i, j - 1] -
4 * self.wave_heights[i, j]) * self.WAVE_SPEED
self.velocities[i, j, 0] *= self.DAMPING
self.velocities[i, j, 1] += self.velocities[i, j, 0]
self.wave_heights[i, j] += self.velocities[i, j, 1]
self.wave_heights[i, j] *= self.DAMPING
# Add a periodic disturbance to the wave height
self.wave_heights[i, j] += np.sin(time.time())
# Set wave heights and velocities at the edges of the grid to zero
self.wave_heights[0, :] = -self.wave_heights[1, :]
self.wave_heights[-1, :] = -self.wave_heights[-2, :]
self.wave_heights[:, 0] = -self.wave_heights[:, 1]
self.wave_heights[:, -1] = -self.wave_heights[:, -2]
self.velocities[0, :, :] = -self.velocities[1, :, :]
self.velocities[-1, :, :] = -self.velocities[-2, :, :]
self.velocities[:, 0, :] = -self.velocities[:, 1, :]
self.velocities[:, -1, :] = -self.velocities[:, -2, :]
# Draw wave
for i in range(self.NUM_POINTS_X):
for j in range(self.NUM_POINTS_Y):
x = i * self.SPACING_X
y = j * self.SPACING_Y
color = abs(self.wave_heights[i, j])
max_value = np.max(np.abs(self.wave_heights))
if max_value != 0:
color /= max_value
else:
color = 0
color = int(color * 255)
pygame.draw.rect(self.screen, (color, color, color), (x, y, self.SPACING_X, self.SPACING_Y))
pygame.display.flip()
self.clock.tick(self.FPS)
# Create an instance of WaveSimulation and run the simulation
wave_simulation = WaveSimulation()
wave_simulation.run()