"""
流体动力学插件数学工具模块
提供流体模拟所需的数学计算功能
"""

import math
from panda3d.core import Vec3, Point3

class FluidMathUtils:
    """
    流体数学工具类
    提供流体模拟所需的数学计算功能
    """
    
    @staticmethod
    def dot_product(a, b):
        """
        计算两个向量的点积
        
        Args:
            a (Vec3): 向量a
            b (Vec3): 向量b
            
        Returns:
            float: 点积结果
        """
        return a.dot(b)
        
    @staticmethod
    def cross_product(a, b):
        """
        计算两个向量的叉积
        
        Args:
            a (Vec3): 向量a
            b (Vec3): 向量b
            
        Returns:
            Vec3: 叉积结果
        """
        return a.cross(b)
        
    @staticmethod
    def vector_length(v):
        """
        计算向量长度
        
        Args:
            v (Vec3): 向量
            
        Returns:
            float: 向量长度
        """
        return v.length()
        
    @staticmethod
    def normalize_vector(v):
        """
        归一化向量
        
        Args:
            v (Vec3): 向量
            
        Returns:
            Vec3: 归一化后的向量
        """
        if v.length() > 0:
            return v.normalized()
        return Vec3(0, 0, 0)
        
    @staticmethod
    def distance(a, b):
        """
        计算两点间距离
        
        Args:
            a (Point3): 点a
            b (Point3): 点b
            
        Returns:
            float: 距离
        """
        return (a - b).length()
        
    @staticmethod
    def interpolate(a, b, t):
        """
        线性插值
        
        Args:
            a (float): 起始值
            b (float): 终止值
            t (float): 插值参数 (0-1)
            
        Returns:
            float: 插值结果
        """
        return a + (b - a) * t
        
    @staticmethod
    def clamp(value, min_val, max_val):
        """
        限制值在指定范围内
        
        Args:
            value (float): 值
            min_val (float): 最小值
            max_val (float): 最大值
            
        Returns:
            float: 限制后的值
        """
        return max(min_val, min(max_val, value))
        
    @staticmethod
    def smoothstep(edge0, edge1, x):
        """
        平滑步进函数
        
        Args:
            edge0 (float): 起始边缘
            edge1 (float): 终止边缘
            x (float): 输入值
            
        Returns:
            float: 平滑步进结果
        """
        t = FluidMathUtils.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
        return t * t * (3.0 - 2.0 * t)
        
    @staticmethod
    def calculate_pressure(density, rest_density, gas_constant):
        """
        计算压力（状态方程）
        
        Args:
            density (float): 当前密度
            rest_density (float): 静止密度
            gas_constant (float): 气体常数
            
        Returns:
            float: 压力值
        """
        # 简单的状态方程: P = k * (ρ - ρ₀)
        return gas_constant * (density - rest_density)
        
    @staticmethod
    def calculate_viscosity_force(velocity_diff, viscosity, distance, radius):
        """
        计算粘性力
        
        Args:
            velocity_diff (Vec3): 速度差
            viscosity (float): 粘度
            distance (float): 距离
            radius (float): 影响半径
            
        Returns:
            Vec3: 粘性力
        """
        # 基于距离的权重
        weight = 1.0 - distance / radius if distance < radius else 0.0
        # 粘性力与速度差和粘度成正比
        return velocity_diff * viscosity * weight
        
    @staticmethod
    def calculate_surface_tension_force(normal, surface_tension, curvature):
        """
        计算表面张力力
        
        Args:
            normal (Vec3): 表面法线
            surface_tension (float): 表面张力系数
            curvature (float): 曲率
            
        Returns:
            Vec3: 表面张力力
        """
        # 表面张力力与曲率和法线方向有关
        return normal * surface_tension * curvature
        
    @staticmethod
    def calculate_buoyancy(density_diff, gravity):
        """
        计算浮力
        
        Args:
            density_diff (float): 密度差
            gravity (Vec3): 重力向量
            
        Returns:
            Vec3: 浮力
        """
        # 浮力与密度差和重力成正比
        return gravity * density_diff
        
    @staticmethod
    def calculate_drag_force(velocity, drag_coefficient, fluid_density, area):
        """
        计算阻力
        
        Args:
            velocity (Vec3): 速度向量
            drag_coefficient (float): 阻力系数
            fluid_density (float): 流体密度
            area (float): 参考面积
            
        Returns:
            Vec3: 阻力向量
        """
        speed = velocity.length()
        if speed > 0:
            # 阻力公式: F = 0.5 * ρ * v² * Cd * A
            drag_magnitude = 0.5 * fluid_density * speed * speed * drag_coefficient * area
            drag_direction = -velocity.normalized()
            return drag_direction * drag_magnitude
        return Vec3(0, 0, 0)