64 lines
2.6 KiB
Python
64 lines
2.6 KiB
Python
|
|
import math
|
||
|
|
from typing import Tuple
|
||
|
|
|
||
|
|
|
||
|
|
# ══════════════════════════════════════════════════════════════════════
|
||
|
|
# 风场模型(保持不变,略)
|
||
|
|
# ══════════════════════════════════════════════════════════════════════
|
||
|
|
|
||
|
|
class WindField:
|
||
|
|
"""风场模型(同前版本,此处省略重复代码)"""
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
self._uniform_dir: float = 0.0
|
||
|
|
self._uniform_spd: float = 0.0
|
||
|
|
self._layers: list = []
|
||
|
|
|
||
|
|
def set_uniform(self, direction_deg: float, speed_ms: float):
|
||
|
|
self._uniform_dir = direction_deg % 360.0
|
||
|
|
self._uniform_spd = max(0.0, speed_ms)
|
||
|
|
|
||
|
|
def add_layer(self, altitude_m: float,
|
||
|
|
direction_deg: float, speed_ms: float):
|
||
|
|
from dataclasses import dataclass as _dc
|
||
|
|
@_dc
|
||
|
|
class _L:
|
||
|
|
altitude_m: float
|
||
|
|
wind_dir_deg: float
|
||
|
|
wind_speed_ms: float
|
||
|
|
self._layers.append(
|
||
|
|
_L(altitude_m, direction_deg % 360.0, max(0.0, speed_ms))
|
||
|
|
)
|
||
|
|
self._layers.sort(key=lambda x: x.altitude_m)
|
||
|
|
|
||
|
|
def get_wind(self, altitude_m: float) -> Tuple[float, float]:
|
||
|
|
if not self._layers:
|
||
|
|
return self._uniform_dir, self._uniform_spd
|
||
|
|
if altitude_m <= self._layers[0].altitude_m:
|
||
|
|
lo = self._layers[0]
|
||
|
|
return lo.wind_dir_deg, lo.wind_speed_ms
|
||
|
|
if altitude_m >= self._layers[-1].altitude_m:
|
||
|
|
hi = self._layers[-1]
|
||
|
|
return hi.wind_dir_deg, hi.wind_speed_ms
|
||
|
|
lo_idx, hi_idx = 0, len(self._layers) - 1
|
||
|
|
while hi_idx - lo_idx > 1:
|
||
|
|
mid = (lo_idx + hi_idx) // 2
|
||
|
|
if self._layers[mid].altitude_m <= altitude_m:
|
||
|
|
lo_idx = mid
|
||
|
|
else:
|
||
|
|
hi_idx = mid
|
||
|
|
lo, hi = self._layers[lo_idx], self._layers[hi_idx]
|
||
|
|
dh = hi.altitude_m - lo.altitude_m
|
||
|
|
t = (altitude_m - lo.altitude_m) / dh if dh > 0 else 0.0
|
||
|
|
spd = lo.wind_speed_ms * (1-t) + hi.wind_speed_ms * t
|
||
|
|
d = hi.wind_dir_deg - lo.wind_dir_deg
|
||
|
|
if d > 180.0: d -= 360.0
|
||
|
|
if d < -180.0: d += 360.0
|
||
|
|
return (lo.wind_dir_deg + d * t) % 360.0, spd
|
||
|
|
|
||
|
|
def get_wind_vector(self, altitude_m: float) -> Tuple[float, float]:
|
||
|
|
wd, ws = self.get_wind(altitude_m)
|
||
|
|
wt = math.radians((wd + 180.0) % 360.0)
|
||
|
|
return ws * math.sin(wt), ws * math.cos(wt)
|
||
|
|
|