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