ここは 「惑星=連続関数」から “意味のある地形カテゴリ” を抽出する OS レイヤ だから、
地形万華鏡の PlanetSpace → HeightSpace → BiomeSpace の変換を、
破綻しない数学として定義していくね。
あなたの惑星生成エンジンはすでに:
- 方向ベクトル → OctaSpace → ノイズ関数 → height(0〜1)
まで来ている。
ここから先は height を 意味のある地形カテゴリ に分類する。
🌍 OS の地形分類レイヤ(Height → TerrainType)
地形万華鏡 OS では、height はただの数値ではなく
「惑星の意味」 に変換される。
分類はこの 4 つ:
- 海(Ocean)
- 陸(Land)
- 山脈(Mountain)
- 河川(River)
これを height と勾配(slope) から決める。
🧭 1. 海 / 陸 の分類(Sea Level)
海面は惑星パラメータとして持つ:
SEA_LEVEL = 0.48
分類:
if h < SEA_LEVEL:
return "ocean"
else:
return "land"
⛰ 2. 山脈(Mountain)の分類(局所的な高さ)
山脈は 周囲よりどれだけ高いか で決める。
必要なのは:
- height(その点の標高)
- 周囲の平均(3×3 or 5×5)
- 標高差(local prominence)
def is_mountain(h, neighbors, threshold=0.12):
avg = sum(neighbors) / len(neighbors)
return (h - avg) > threshold
閾値は惑星パラメータで調整可能。
🌊 3. 河川(River)の分類(標高勾配ベース)
河川は 低標高ではなく “水が集まる場所” で決まる。
OS 的には:
- 勾配(gradient)
- 流量(flow accumulation)
を使う。
3-1. 勾配(gradient)
dx = h_right - h_left
dy = h_down - h_up
slope = math.sqrt(dx*dx + dy*dy)
3-2. 流量(flow accumulation)
これは 水がどこに流れ込むか を計算する。
def flow_direction(h, neighbors):
# 最も低い方向へ流す
min_h = min(neighbors, key=lambda x: x[2])
return min_h[0], min_h[1] # (dx, dy)
流量は:
flow[y][x] += 1 + flow[y+dy][x+dx]
3-3. 河川判定
if flow[y][x] > FLOW_THRESHOLD and h > SEA_LEVEL:
return "river"
🧪 4. すべてをまとめた Python コード
def classify_terrain(h, neighbors, flow, sea_level=0.48,
mountain_threshold=0.12, river_threshold=20):
# 海
if h < sea_level:
return "ocean"
# 河川(陸地で流量が大きい)
if flow > river_threshold:
return "river"
# 山脈(周囲より高い)
avg = sum(neighbors) / len(neighbors)
if (h - avg) > mountain_threshold:
return "mountain"
# それ以外は陸
return "land"
🌌 5. OS としての意味レイヤ構造
あなたの惑星生成 OS はこうなる:
PlanetSpace(方向ベクトル)
↓
OctaSpace(U,V)
↓
NoiseSpace(height)
↓
HeightSpace(0〜1)
↓
TerrainSpace(ocean / land / mountain / river)
↓
BiomeSpace(forest / desert / tundra / swamp)
今は TerrainSpace を作ったところ。
🧭 次に深めるなら…
- BiomeSpace(気温×湿度×標高)で森・砂漠・ツンドラを分類
- 河川を実際に “線” として抽出する(流路生成)
- Roblox チャンクに TerrainType を焼き込む IR 設計
- プレートテクトニクスと山脈生成の連動
どこに進めたい?