File size: 3,372 Bytes
2afa69c | 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 | import numpy as np
from dataclasses import dataclass, field
from typing import Tuple, Optional
@dataclass
class WorldGrid:
"""
์ง๊ตฌ ์์คํ
ํตํฉ ๊ทธ๋ฆฌ๋ (World Grid)
๋ชจ๋ ๋ฌผ๋ฆฌ์ ์ํ(๊ณ ๋, ๋ฌผ, ํด์ ๋ฌผ)๋ฅผ ํตํฉ ๊ด๋ฆฌํ๋ ์ค์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์
๋๋ค.
๊ธฐ์กด์ ๊ฐ๋ณ ์๋ฎฌ๋ ์ด์
๊ทธ๋ฆฌ๋์ ๋ฌ๋ฆฌ, ์ ์ง๊ตฌ์ ํด์๋ฉด(Sea Level)๊ณผ ์ฐ๋๋ฉ๋๋ค.
"""
width: int = 100
height: int = 100
cell_size: float = 10.0 # ๋ฏธํฐ (m)
sea_level: float = 0.0 # ํด์๋ฉด ๊ณ ๋ (m)
# --- ์ํ ๋ ์ด์ด (State Layers) ---
# ๊ธฐ๋ฐ์ ๊ณ ๋ (Bedrock Elevation)
bedrock: np.ndarray = field(default=None)
# ํด์ ์ธต ๋๊ป (Sediment Thickness)
sediment: np.ndarray = field(default=None)
# ์์ฌ (Water Depth) - ํ๋ฉด ์ ์ถ์
water_depth: np.ndarray = field(default=None)
# ์ ๋ (Discharge)
discharge: np.ndarray = field(default=None)
# ์ ํฅ (Flow Direction)
flow_dir: np.ndarray = field(default=None)
# --- ํ์ ๋ ์ด์ด (Derived Layers) ---
# ์งํ๋ฉด ๊ณ ๋ (Topography = Bedrock + Sediment)
elevation: np.ndarray = field(default=None)
def __post_init__(self):
"""๊ทธ๋ฆฌ๋ ์ด๊ธฐํ"""
shape = (self.height, self.width)
if self.bedrock is None:
self.bedrock = np.zeros(shape)
if self.sediment is None:
self.sediment = np.zeros(shape)
if self.water_depth is None:
self.water_depth = np.zeros(shape)
if self.discharge is None:
self.discharge = np.zeros(shape)
if self.flow_dir is None:
self.flow_dir = np.zeros(shape, dtype=int)
if self.elevation is None:
self.update_elevation()
def update_elevation(self):
"""์งํ๋ฉด ๊ณ ๋ ๊ฐฑ์ (๊ธฐ๋ฐ์ + ํด์ ์ธต)"""
self.elevation = self.bedrock + self.sediment
def get_gradient(self) -> Tuple[np.ndarray, np.ndarray]:
"""
๊ฒฝ์ฌ๋(Slope)์ ๊ฒฝ์ฌํฅ(Aspect) ๊ณ์ฐ
Returns:
slope (m/m): ๊ฒฝ์ฌ๋
aspect (rad): ๊ฒฝ์ฌ ๋ฐฉํฅ (0=East, pi/2=North)
"""
dy, dx = np.gradient(self.elevation, self.cell_size)
slope = np.sqrt(dx**2 + dy**2)
aspect = np.arctan2(dy, dx)
return slope, aspect
def get_water_surface(self) -> np.ndarray:
"""์๋ฉด ๊ณ ๋ ๋ฐํ (์งํ๋ฉด + ์์ฌ)"""
return self.elevation + self.water_depth
def is_underwater(self) -> np.ndarray:
"""ํด์๋ฉด ๊ธฐ์ค ์นจ์ ์ฌ๋ถ ํ์ธ"""
# ํด์๋ฉด๋ณด๋ค ๋ฎ๊ฑฐ๋, ์งํ๋ฉด์ ๋ฌผ์ด ํ๋ฅด๊ณ ์๋ ๊ฒฝ์ฐ
# ์ฌ๊ธฐ์๋ ๊ฐ๋จํ 'ํด์๋ฉด' ๊ธฐ์ค๊ณผ '๋ด์' ์กด์ฌ ์ฌ๋ถ๋ฅผ ๋ถ๋ฆฌํด์ ์๊ฐํ ์ ์์.
# ์ผ๋จ ํด์๋ฉด(Sea Level) ๊ธฐ์ค ์นจ์ ์ง์ญ ๋ฐํ
return self.elevation < self.sea_level
def apply_uplift(self, rate: float, dt: float = 1.0):
"""์ง๋ฐ ์ต๊ธฐ ์ ์ฉ"""
self.bedrock += rate * dt
self.update_elevation()
def add_sediment(self, amount: np.ndarray):
"""ํด์ ๋ฌผ ์ถ๊ฐ/์ ๊ฑฐ"""
self.sediment += amount
# ํด์ ๋ฌผ์ 0๋ณด๋ค ์์ ์ ์์ (๊ธฐ๋ฐ์ ์นจ์์ ๋ณ๋ ๋ก์ง)
self.sediment = np.maximum(self.sediment, 0)
self.update_elevation()
|