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()