""" 波浪系统模块 负责生成和管理各种类型的波浪效果 """ import time from typing import Dict, Any, List, Optional import math import numpy as np class WaveSystem: """ 波浪系统 负责生成和管理各种类型的波浪效果,包括风浪、涌浪、涟漪等 """ def __init__(self, plugin): """ 初始化波浪系统 Args: plugin: 水体和流体模拟插件实例 """ self.plugin = plugin self.enabled = False self.initialized = False # 波浪类型定义 self.wave_types = { 'wind_wave': { 'name': '风浪', 'description': '由风力产生的波浪', 'frequency_range': (0.1, 1.0), # Hz 'amplitude_range': (0.01, 2.0), # 米 'speed_range': (1.0, 10.0), # m/s 'typical_wavelength': 10.0 # 米 }, 'swell_wave': { 'name': '涌浪', 'description': '远处风暴产生的长周期波浪', 'frequency_range': (0.05, 0.2), 'amplitude_range': (0.5, 5.0), 'speed_range': (5.0, 20.0), 'typical_wavelength': 100.0 }, 'ripple': { 'name': '涟漪', 'description': '小尺度的表面波纹', 'frequency_range': (1.0, 10.0), 'amplitude_range': (0.001, 0.05), 'speed_range': (0.1, 1.0), 'typical_wavelength': 0.1 }, 'tsunami': { 'name': '海啸', 'description': '由地震或海底滑坡产生的巨大波浪', 'frequency_range': (0.001, 0.01), 'amplitude_range': (1.0, 50.0), 'speed_range': (50.0, 200.0), 'typical_wavelength': 100000.0 }, 'ship_wave': { 'name': '船行波', 'description': '船舶运动产生的波浪', 'frequency_range': (0.1, 2.0), 'amplitude_range': (0.1, 1.0), 'speed_range': (0.5, 5.0), 'typical_wavelength': 5.0 } } # 活跃波浪列表 self.active_waves = [] self.wave_counter = 0 # 波浪谱配置 self.wave_spectrum = { 'type': 'pierson_moskowitz', # 'pierson_moskowitz', 'jonswap', 'custom' 'wind_speed': 10.0, # m/s 'fetch': 10000.0, # 风区长度(米) 'duration': 3600.0, # 风持续时间(秒) 'peak_frequency': 0.2, # Hz 'significant_wave_height': 1.0 # 有效波高(米) } # 动态波浪配置 self.dynamic_config = { 'max_waves': 32, 'update_frequency': 60.0, # Hz 'last_update_time': 0.0, 'time_scale': 1.0 } # 环境影响因子 self.environment_factors = { 'wind_speed': 5.0, # m/s 'wind_direction': 0.0, # 弧度 'water_depth': 10.0, # 米 'current_velocity': (0.0, 0.0), # (vx, vz) m/s 'temperature': 20.0, # °C 'salinity': 35.0 # ppt } # 波浪统计 self.wave_stats = { 'total_waves': 0, 'active_waves': 0, 'total_energy': 0.0, 'peak_wave_height': 0.0, 'average_wave_period': 0.0 } # 交互效果 self.interaction_effects = { 'splash_damping': 0.9, # 溅起波浪的阻尼系数 'wave_interference': True, # 是否启用波浪干涉 'nonlinear_effects': True, # 是否启用非线性效应 'breaking_waves': True # 是否启用碎浪效果 } print("✓ 波浪系统已创建") def initialize(self) -> bool: """ 初始化波浪系统 Returns: 是否初始化成功 """ try: # 创建一些初始波浪 self._create_initial_waves() self.initialized = True print("✓ 波浪系统初始化完成") return True except Exception as e: print(f"✗ 波浪系统初始化失败: {e}") import traceback traceback.print_exc() return False def enable(self) -> bool: """ 启用波浪系统 Returns: 是否启用成功 """ try: if not self.initialized: print("✗ 波浪系统未初始化") return False self.enabled = True print("✓ 波浪系统已启用") return True except Exception as e: print(f"✗ 波浪系统启用失败: {e}") import traceback traceback.print_exc() return False def disable(self): """禁用波浪系统""" try: self.enabled = False print("✓ 波浪系统已禁用") except Exception as e: print(f"✗ 波浪系统禁用失败: {e}") import traceback traceback.print_exc() def finalize(self): """清理波浪系统资源""" try: self.disable() self.active_waves.clear() self.initialized = False print("✓ 波浪系统资源已清理") except Exception as e: print(f"✗ 波浪系统资源清理失败: {e}") import traceback traceback.print_exc() def update(self, dt: float): """ 更新波浪系统状态 Args: dt: 时间增量 """ try: if not self.enabled: return # 更新时间 self.dynamic_config['last_update_time'] += dt * self.dynamic_config['time_scale'] # 更新活跃波浪 self._update_active_waves(dt) # 根据环境条件生成新波浪 self._generate_environment_waves(dt) # 更新统计信息 self._update_wave_statistics() except Exception as e: print(f"✗ 波浪系统更新失败: {e}") import traceback traceback.print_exc() def _create_initial_waves(self): """创建初始波浪""" try: # 创建几个默认波浪 for i in range(3): wave_params = { 'type': 'wind_wave', 'amplitude': 0.5 + i * 0.2, 'wavelength': 10.0 + i * 5.0, 'speed': 2.0 + i * 0.5, 'direction': i * math.pi / 3, 'frequency': 0.3 + i * 0.1, 'phase': 0.0, 'damping': 0.01, 'lifetime': float('inf'), 'position': (0.0, 0.0) } self._add_wave(wave_params) print("✓ 初始波浪创建完成") except Exception as e: print(f"✗ 初始波浪创建失败: {e}") def _update_active_waves(self, dt: float): """ 更新活跃波浪 Args: dt: 时间增量 """ try: time_value = self.dynamic_config['last_update_time'] # 更新每个波浪 waves_to_remove = [] for wave in self.active_waves: # 更新相位 wave['phase'] += wave['frequency'] * 2 * math.pi * dt # 应用阻尼 wave['amplitude'] *= (1.0 - wave['damping'] * dt) # 检查生命周期 if wave['lifetime'] != float('inf'): wave['lifetime'] -= dt if wave['lifetime'] <= 0: waves_to_remove.append(wave) # 更新位置(考虑水流速度) current_vx, current_vz = self.environment_factors['current_velocity'] wave['position'] = ( wave['position'][0] + current_vx * dt, wave['position'][1] + current_vz * dt ) # 移除过期波浪 for wave in waves_to_remove: self.active_waves.remove(wave) except Exception as e: print(f"✗ 活跃波浪更新失败: {e}") def _generate_environment_waves(self, dt: float): """ 根据环境条件生成波浪 Args: dt: 时间增量 """ try: # 基于风速生成波浪 wind_speed = self.environment_factors['wind_speed'] wind_direction = self.environment_factors['wind_direction'] # 简化的波浪生成逻辑 # 实际实现中会使用更复杂的波浪谱模型 wave_generation_probability = min(1.0, wind_speed / 20.0) * dt if np.random.random() < wave_generation_probability and len(self.active_waves) < self.dynamic_config['max_waves']: # 生成新波浪 wave_type = 'wind_wave' wave_info = self.wave_types[wave_type] # 根据风速确定波浪参数 amplitude = np.random.uniform(0.1, wind_speed / 5.0) wavelength = np.random.uniform(5.0, max(5.0, wind_speed * 2.0)) speed = min(wind_speed, math.sqrt(9.81 * wavelength / (2 * math.pi))) # 深水波速 direction = wind_direction + np.random.uniform(-0.2, 0.2) # 小角度偏移 wave_params = { 'type': wave_type, 'amplitude': amplitude, 'wavelength': wavelength, 'speed': speed, 'direction': direction, 'frequency': speed / wavelength, 'phase': np.random.uniform(0, 2 * math.pi), 'damping': np.random.uniform(0.001, 0.01), 'lifetime': np.random.uniform(10.0, 60.0), 'position': (0.0, 0.0) } self._add_wave(wave_params) except Exception as e: print(f"✗ 环境波浪生成失败: {e}") def _add_wave(self, wave_params: Dict[str, Any]) -> int: """ 添加波浪 Args: wave_params: 波浪参数 Returns: 波浪ID """ try: wave_id = self.wave_counter self.wave_counter += 1 wave_params['id'] = wave_id wave_params['creation_time'] = self.dynamic_config['last_update_time'] self.active_waves.append(wave_params) return wave_id except Exception as e: print(f"✗ 波浪添加失败: {e}") return -1 def _update_wave_statistics(self): """更新波浪统计信息""" try: total_energy = 0.0 peak_height = 0.0 total_period = 0.0 for wave in self.active_waves: # 波浪能量 (简化的计算) energy = 0.5 * 1000.0 * 9.81 * wave['amplitude'] ** 2 total_energy += energy # 峰值波高 peak_height = max(peak_height, wave['amplitude'] * 2) # 波峰到波谷 # 平均周期 if wave['frequency'] > 0: total_period += 1.0 / wave['frequency'] self.wave_stats['total_waves'] = self.wave_counter self.wave_stats['active_waves'] = len(self.active_waves) self.wave_stats['total_energy'] = total_energy self.wave_stats['peak_wave_height'] = peak_height if len(self.active_waves) > 0: self.wave_stats['average_wave_period'] = total_period / len(self.active_waves) else: self.wave_stats['average_wave_period'] = 0.0 except Exception as e: print(f"✗ 波浪统计更新失败: {e}") def create_wave(self, wave_type: str, parameters: Dict[str, Any]) -> int: """ 创建指定类型的波浪 Args: wave_type: 波浪类型 parameters: 波浪参数 Returns: 波浪ID """ try: if wave_type not in self.wave_types: print(f"✗ 无效的波浪类型: {wave_type}") return -1 # 获取波浪类型信息 wave_info = self.wave_types[wave_type] # 默认参数 default_params = { 'type': wave_type, 'amplitude': np.random.uniform(*wave_info['amplitude_range']), 'wavelength': wave_info['typical_wavelength'], 'speed': np.random.uniform(*wave_info['speed_range']), 'direction': np.random.uniform(0, 2 * math.pi), 'frequency': 0.0, 'phase': 0.0, 'damping': 0.01, 'lifetime': float('inf'), 'position': (0.0, 0.0) } # 更新默认参数 default_params.update(parameters) # 计算频率(如果未提供) if default_params['frequency'] <= 0: if default_params['wavelength'] > 0: default_params['frequency'] = default_params['speed'] / default_params['wavelength'] else: default_params['frequency'] = 0.1 # 添加波浪 wave_id = self._add_wave(default_params) if wave_id >= 0: print(f"✓ {wave_info['name']} 已创建 (ID: {wave_id})") return wave_id except Exception as e: print(f"✗ 波浪创建失败: {e}") return -1 def remove_wave(self, wave_id: int) -> bool: """ 移除波浪 Args: wave_id: 波浪ID Returns: 是否移除成功 """ try: for wave in self.active_waves: if wave['id'] == wave_id: self.active_waves.remove(wave) print(f"✓ 波浪已移除 (ID: {wave_id})") return True print(f"✗ 波浪不存在 (ID: {wave_id})") return False except Exception as e: print(f"✗ 波浪移除失败: {e}") return False def get_wave(self, wave_id: int) -> Optional[Dict[str, Any]]: """ 获取波浪信息 Args: wave_id: 波浪ID Returns: 波浪信息或None """ try: for wave in self.active_waves: if wave['id'] == wave_id: return wave.copy() return None except Exception as e: print(f"✗ 波浪信息获取失败: {e}") return None def get_all_waves(self) -> List[Dict[str, Any]]: """ 获取所有活跃波浪 Returns: 波浪列表 """ return [wave.copy() for wave in self.active_waves] def calculate_wave_height_at(self, x: float, z: float, time_value: float = None) -> float: """ 计算指定位置和时间的波浪高度 Args: x, z: 位置坐标 time_value: 时间值(如果为None则使用当前时间) Returns: 波浪高度 """ try: if time_value is None: time_value = self.dynamic_config['last_update_time'] total_height = 0.0 # 计算每个波浪在该点的贡献 for wave in self.active_waves: # 计算相对于波浪位置的距离 dx = x - wave['position'][0] dz = z - wave['position'][1] # 计算在波浪传播方向上的投影距离 direction = wave['direction'] projection = dx * math.cos(direction) + dz * math.sin(direction) # 计算相位 phase = wave['phase'] + 2 * math.pi * projection / wave['wavelength'] # 计算波浪高度(正弦波) height = wave['amplitude'] * math.sin(phase) # 如果启用波浪干涉,直接叠加 if self.interaction_effects['wave_interference']: total_height += height else: # 否则取最大值 total_height = max(total_height, height) return total_height except Exception as e: print(f"✗ 波浪高度计算失败: {e}") return 0.0 def calculate_wave_velocity_at(self, x: float, z: float, time_value: float = None) -> tuple: """ 计算指定位置和时间的波浪速度 Args: x, z: 位置坐标 time_value: 时间值(如果为None则使用当前时间) Returns: 波浪速度 (vx, vz) """ try: if time_value is None: time_value = self.dynamic_config['last_update_time'] total_vx = 0.0 total_vz = 0.0 # 计算每个波浪在该点的速度贡献 for wave in self.active_waves: # 计算相对于波浪位置的距离 dx = x - wave['position'][0] dz = z - wave['position'][1] # 计算在波浪传播方向上的投影距离 direction = wave['direction'] projection = dx * math.cos(direction) + dz * math.sin(direction) # 计算相位 phase = wave['phase'] + 2 * math.pi * projection / wave['wavelength'] # 计算速度分量 speed = wave['speed'] vx = speed * math.cos(direction) vz = speed * math.sin(direction) # 考虑波浪振幅的影响 velocity_factor = wave['amplitude'] * math.cos(phase) total_vx += vx * velocity_factor total_vz += vz * velocity_factor return (total_vx, total_vz) except Exception as e: print(f"✗ 波浪速度计算失败: {e}") return (0.0, 0.0) def generate_wave_spectrum(self) -> Dict[str, List[float]]: """ 生成波浪谱 Returns: 包含频率和能量密度的字典 """ try: spectrum_type = self.wave_spectrum['type'] wind_speed = self.wave_spectrum['wind_speed'] # 频率范围 freq_min, freq_max = 0.01, 2.0 num_points = 100 frequencies = np.linspace(freq_min, freq_max, num_points) energy_densities = np.zeros(num_points) if spectrum_type == 'pierson_moskowitz': # Pierson-Moskowitz谱 alpha = 8.1e-3 beta = 0.74 g = 9.81 for i, f in enumerate(frequencies): if f > 0: omega = 2 * math.pi * f energy_densities[i] = alpha * g**2 / omega**5 * math.exp(-beta * (g / (omega * wind_speed))**4) elif spectrum_type == 'jonswap': # JONSWAP谱 alpha = 0.076 * (wind_speed**2 / (g * 100))**0.22 # 简化计算 beta = 0.74 gamma = 3.3 # 峰值增强因子 sigma = 0.07 # 谱宽参数 fp = self.wave_spectrum['peak_frequency'] omega_p = 2 * math.pi * fp for i, f in enumerate(frequencies): if f > 0: omega = 2 * math.pi * f ratio = omega / omega_p # 谱宽参数 if ratio <= 1: sigma_val = 0.07 else: sigma_val = 0.09 # 峰值增强函数 gamma_val = gamma ** math.exp(-0.5 * ((ratio - 1) / sigma_val)**2) energy_densities[i] = alpha * g**2 / omega**5 * math.exp(-beta * (g / (omega * wind_speed))**4) * gamma_val return { 'frequencies': frequencies.tolist(), 'energy_densities': energy_densities.tolist() } except Exception as e: print(f"✗ 波浪谱生成失败: {e}") return { 'frequencies': [], 'energy_densities': [] } def create_splash_wave(self, position: tuple, energy: float) -> List[int]: """ 创建溅起波浪效果 Args: position: 溅起位置 (x, z) energy: 溅起能量 Returns: 创建的波浪ID列表 """ try: created_waves = [] # 创建多个同心圆波浪来模拟溅起效果 num_ripples = min(5, int(energy / 0.1)) for i in range(num_ripples): amplitude = energy * 0.1 * (1.0 - i * 0.15) wavelength = 0.5 + i * 0.3 speed = 1.0 + i * 0.5 lifetime = 2.0 + i * 0.5 wave_params = { 'type': 'ripple', 'amplitude': amplitude, 'wavelength': wavelength, 'speed': speed, 'direction': 0.0, # 径向波 'frequency': speed / wavelength, 'phase': 0.0, 'damping': 0.5, 'lifetime': lifetime, 'position': position } wave_id = self._add_wave(wave_params) if wave_id >= 0: created_waves.append(wave_id) if created_waves: print(f"✓ 溅起波浪已创建 ({len(created_waves)} 个波浪)") return created_waves except Exception as e: print(f"✗ 溅起波浪创建失败: {e}") return [] def update_environment_factors(self, factors: Dict[str, Any]): """ 更新环境因子 Args: factors: 环境因子字典 """ try: self.environment_factors.update(factors) print(f"✓ 环境因子已更新: {factors}") except Exception as e: print(f"✗ 环境因子更新失败: {e}") def get_environment_factors(self) -> Dict[str, Any]: """ 获取环境因子 Returns: 环境因子字典 """ return self.environment_factors.copy() def set_wave_spectrum(self, spectrum: Dict[str, Any]): """ 设置波浪谱参数 Args: spectrum: 波浪谱参数字典 """ try: self.wave_spectrum.update(spectrum) print(f"✓ 波浪谱参数已更新: {self.wave_spectrum}") except Exception as e: print(f"✗ 波浪谱参数设置失败: {e}") def get_wave_spectrum(self) -> Dict[str, Any]: """ 获取波浪谱参数 Returns: 波浪谱参数字典 """ return self.wave_spectrum.copy() def set_dynamic_config(self, config: Dict[str, Any]): """ 设置动态配置 Args: config: 动态配置字典 """ try: self.dynamic_config.update(config) print(f"✓ 动态配置已更新: {self.dynamic_config}") except Exception as e: print(f"✗ 动态配置设置失败: {e}") def get_dynamic_config(self) -> Dict[str, Any]: """ 获取动态配置 Returns: 动态配置字典 """ return self.dynamic_config.copy() def get_wave_statistics(self) -> Dict[str, Any]: """ 获取波浪统计信息 Returns: 波浪统计字典 """ return self.wave_stats.copy() def reset_wave_statistics(self): """重置波浪统计信息""" try: self.wave_stats = { 'total_waves': self.wave_counter, 'active_waves': len(self.active_waves), 'total_energy': 0.0, 'peak_wave_height': 0.0, 'average_wave_period': 0.0 } print("✓ 波浪统计信息已重置") except Exception as e: print(f"✗ 波浪统计信息重置失败: {e}") def get_wave_types(self) -> List[str]: """ 获取所有波浪类型 Returns: 波浪类型列表 """ return list(self.wave_types.keys()) def get_wave_type_info(self, wave_type: str) -> Optional[Dict[str, Any]]: """ 获取波浪类型信息 Args: wave_type: 波浪类型 Returns: 波浪类型信息或None """ return self.wave_types.get(wave_type)