EG/plugins/user/fluid_dynamics/utils/math_utils.py
2025-12-12 16:16:15 +08:00

217 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
流体动力学插件数学工具模块
提供流体模拟所需的数学计算功能
"""
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)