对于单个粒子处理碰撞:
首先,要判断粒子是否穿透了边界,假如穿透了,才发生碰撞。这要通过碰撞检测算法来实现。这个算法很复杂,尤其在涉及多个物体和复杂表面的情况下。我们先不讨论,只讨论最简单的情况。
假设我们已经检测到了碰撞,并且我们知道壁面的法向N。还知道当前粒子的速度和位置。
那么
- 判断 v ⋅ N < 0 ? v\cdot N < 0? v⋅N<0? 前者意味着速度要继续往穿透边界的方向移动。如果不是,意味着粒子已经朝着离开固体的方向移动了,很可能是上一时刻已经处理过,但是暂且还未离开的粒子。
- 根据壁面法向N,把速度拆解为法向和切向。然后法向乘以法向衰减系数并且反向,切向乘以切向衰减系数。但是这里要注意切向衰减系数是要根据库仑摩擦定律计算出来。计算出来的值和法向速度大小与切向速度大小的比值有关。
- 重组法向和切向速度。然后移动粒子。
参考:games103 王华民
import taichi as ti
import random
x = random.randint(0, 9)
y = random.randint(-3, 3)
velocities = ti.Vector([x, y, 0])
print(velocities)
n_dir = ti.Vector([0, 1, 0]).normalized()
vn = velocities.dot(n_dir) * n_dir
vt = velocities - vn
vt_norm = vt.norm()
vn_norm = vn.norm()
print(f"vn_norm:{vn_norm}; vt_norm:{vt_norm}")
if(velocities.dot(n_dir) < 0 and vt_norm != 0):
mu_N = 1
mu_T = 1
vn_new = -mu_N * vn
a = ti.max((1 - mu_T * (1 + mu_N) * vn.norm() / vt_norm ), 0)
print(1 - mu_T * (1 + mu_N) * vn.norm() / vt_norm )
print(f"a={a}")
vt_new = a * vt
v_new = vn_new + vt_new
print(v_new)