Verlet积分器 + 摩擦

3
我一直在Gamedev.net上关注“{{link1:基于Verlet的2D游戏物理方法} }”,并写了类似的东西。
我的问题是,盒子在地面上滑动太多了。我该如何添加一个简单的静止状态,使盒子具有更多的摩擦力,只能滑动很少?

你应该在游戏开发或物理学领域提出这个问题。 - Shep
3个回答

2

只需在运动物体上引入一个小的、恒定的加速度,该加速度指向与运动方向相反的方向。而且确保它实际上不能逆转运动;如果在积分步骤中检测到这一点,只需将速度设置为零。

如果你想更加真实,该加速度应当来自于物体与其所滑动表面之间的法向力成比例的力。

在任何基础物理学教材中都可以找到这一点,称为“动摩擦力”或“滑动摩擦力”。


0
在Verlet积分中:r(t)=2.00*r(t-dt)-1.00*r(t-2dt)+2at²,将乘数更改为1.99和0.99以考虑摩擦力。
编辑:这更加准确:

r(t)=(2.00-friction_mult.)*r(t-dt)-(1.00-friction_mult.)*r(t-2dt)+at²


0
这是一个简单的时间步进方案(使用手动解决LCP的辛欧拉方法)用于具有库仑摩擦和弹簧(摩擦振子)的盒子。
mq'' + kq + mu*sgn(q') = F(t)
import numpy as np
import matplotlib.pyplot as plt

q0 = 0   # initial position
p0 = 0  # initial momentum
t_start = 0   # initial time
t_end = 10   # end time
N = 500 # time points
m = 1   # mass
k = 1   # spring stiffness

muN = 0.5   # friction force (slip and maximal stick)
omega = 1.5   # forcing radian frequency [RAD]
Fstat = 0.1   # static component of external force
Fdyn = 0.6   # amplitude of harmonic external force
F = lambda tt,qq,pp: Fstat + Fdyn*np.sin(omega*tt) - k*qq - muN*np.sign(pp)  # total force, note sign(0)=0 used to disable friction
zero_to_disable_friction = 0

omega0 = np.sqrt(k/m)
print("eigenfrequency   f = {} Hz;   eigen period   T = {} s".format(omega0/(2*np.pi), 2*np.pi/omega0))
print("forcing frequency   f = {} Hz;   forcing period   T = {} s".format(omega/(2*np.pi), 2*np.pi/omega))

time = np.linspace(t_start, t_end, N)   # time grid
h = time[1] - time[0]   # time step
q = np.zeros(N+1)   # position
p = np.zeros(N+1)   # momentum
absFfriction = np.zeros(N+1)

q[0] = q0   
p[0] = p0
for n, tn in enumerate(time):
   
    p1slide = p[n] + h*F(tn, q[n], p[n])   # end-time momentum, assuming sliding
    q1slide = q[n] + h*p1slide/m   # end-time position, assuming sliding
    
    if p[n]*p1slide > 0:   # sliding goes on
        q[n+1] = q1slide
        p[n+1] = p1slide
        absFfriction[n] = muN
        
    else:
        q1stick = q[n]   # assume p1 = 0 at t=tn+h
        Fstick = -p[n]/h - F(tn, q1stick, zero_to_disable_friction)    # friction force needed to stop at t=tn+h
        if np.abs(Fstick) <= muN:
            p[n+1] = 0   # sticking
            q[n+1] = q1stick
            absFfriction[n] = np.abs(Fstick)
        else:  # sliding starts or passes zero crossing of velocity
            q[n+1] = q1slide   # possible refinements (adapt to slip-start or zero crossing)
            p[n+1] = p1slide
            absFfriction[n] = muN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接