3

I have been following "A Verlet based approach for 2D game physics" on Gamedev.net and I have written something similar.

The problem I am having is that the boxes slide along the ground too much. How can I add a simple rested state thing where the boxes will have more friction and only slide a tiny bit?

Bart
  • 19,692
  • 7
  • 68
  • 77
Kachinsky
  • 573
  • 1
  • 7
  • 20

3 Answers3

1

Just introduce a small, constant acceleration on moving objects that points in the direction opposite to the motion. And make sure it can't actually reverse the motion; if you detect that in an integration step, just set the velocity to zero.

If you want to be more realistic, the acceleration should derive from a force which is proportional to the normal force between the object and the surface it's sliding on.

You can find this in any basic physics text, as "kinetic friction" or "sliding friction".

Beta
  • 96,650
  • 16
  • 149
  • 150
0

At the verlet integration: r(t)=2.00*r(t-dt)-1.00*r(t-2dt)+2at² change the multipliers to 1.99 and 0.99 for friction

Edit: this is more true:

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

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
0

Here is a simple time stepping scheme (symplectic Euler method with manually resolved LCP) for a box with Coulomb friction and a spring (frictional oscillator)

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
c69
  • 19,951
  • 7
  • 52
  • 82
Dominik Kern
  • 146
  • 8