121 lines
3.5 KiB
Python
121 lines
3.5 KiB
Python
from typing import Tuple
|
|
import numpy as np
|
|
import noise
|
|
import pygame
|
|
|
|
from utils import clamp
|
|
|
|
SEED = 42
|
|
np.random.seed(SEED)
|
|
|
|
|
|
class WindField:
|
|
def __init__(self, width, height, downscale=10):
|
|
self.width = int(width / downscale)
|
|
self.height = int(height / downscale)
|
|
self.downscale = downscale
|
|
self.field_x = np.zeros((self.width, self.height))
|
|
self.field_y = np.zeros((self.width, self.height))
|
|
|
|
def update(
|
|
self,
|
|
time=0,
|
|
scale=15.0,
|
|
time_scale=2.0,
|
|
octaves=5,
|
|
persistence=0.3,
|
|
lacunarity=4.0,
|
|
):
|
|
for i in range(self.width):
|
|
for j in range(self.height):
|
|
self.field_x[i][j] = noise.pnoise3(
|
|
i / scale,
|
|
j / scale,
|
|
time / time_scale,
|
|
octaves=octaves,
|
|
persistence=persistence,
|
|
lacunarity=lacunarity,
|
|
base=SEED,
|
|
)
|
|
self.field_y[i][j] = noise.pnoise3(
|
|
i / scale,
|
|
j / scale,
|
|
time / time_scale,
|
|
octaves=octaves,
|
|
persistence=persistence,
|
|
lacunarity=lacunarity,
|
|
base=SEED + 1,
|
|
)
|
|
|
|
def draw(self, screen):
|
|
for i in range(self.width):
|
|
for j in range(self.height):
|
|
color = (
|
|
abs(self.field_x[i][j] * 255),
|
|
abs(self.field_y[i][j] * 255),
|
|
0,
|
|
)
|
|
pygame.draw.rect(
|
|
screen,
|
|
color,
|
|
(
|
|
i * self.downscale,
|
|
j * self.downscale,
|
|
self.downscale,
|
|
self.downscale,
|
|
),
|
|
)
|
|
|
|
# draw with get_wind
|
|
# def draw(self, screen):
|
|
# for i in range(self.width * self.downscale):
|
|
# for j in range(self.height * self.downscale):
|
|
# wind = self.get_wind((i, j))
|
|
# color = (
|
|
# abs(wind[0] * 255),
|
|
# abs(wind[1] * 255),
|
|
# 0,
|
|
# )
|
|
# pygame.draw.rect(
|
|
# screen,
|
|
# color,
|
|
# (
|
|
# i,
|
|
# j,
|
|
# 1,
|
|
# 1,
|
|
# ),
|
|
# )
|
|
|
|
def get_wind(self, position: Tuple[int, int]) -> Tuple[float, float]:
|
|
x, y = position
|
|
x /= self.downscale
|
|
y /= self.downscale
|
|
|
|
x0 = int(x)
|
|
y0 = int(y)
|
|
x1 = x0 + 1
|
|
y1 = y0 + 1
|
|
|
|
x0 = clamp(x0, 0, self.width - 1)
|
|
y0 = clamp(y0, 0, self.height - 1)
|
|
x1 = clamp(x1, 0, self.width - 1)
|
|
y1 = clamp(y1, 0, self.height - 1)
|
|
|
|
dx = x - x0
|
|
dy = y - y0
|
|
|
|
wind_x = (
|
|
(1 - dx) * (1 - dy) * self.field_x[x0][y0]
|
|
+ dx * (1 - dy) * self.field_x[x1][y0]
|
|
+ (1 - dx) * dy * self.field_x[x0][y1]
|
|
+ dx * dy * self.field_x[x1][y1]
|
|
)
|
|
wind_y = (
|
|
(1 - dx) * (1 - dy) * self.field_y[x0][y0]
|
|
+ dx * (1 - dy) * self.field_y[x1][y0]
|
|
+ (1 - dx) * dy * self.field_y[x0][y1]
|
|
+ dx * dy * self.field_y[x1][y1]
|
|
)
|
|
|
|
return wind_x, wind_y
|