Search code examples
game-physics

Particles behave strangely in my physics engine


I am building a 2D particle simulation program, and I have run into a problem. Any two particles with charges q1 and q2 and masses m1 and m2 with distance r between their centers experience force according to this law:

Fq = K * (q1 * q2) / (r2)
Fc = C * sqrt(m1 * m2) / (r3)

K and C are constants.

Two particles with the charges of the same sign repell and two particles with opposite charge signs attract. Two particles with different-signed charges should eventually find equilibrium, but I run into a problem: when two particles get really close together, they can behave in a weird way. It seems that they:
a) spend much less energy to get to a higher energy state and start running around the chamber like crazy when they get very close to each other. This usually happens when (C/K) is not very big (C=10, K=5) or if precision constant is low.
b) stick to each other and start moving, again, gaining energy, with (C/K) being quite big i.e. (C=50, K=5) (see https://i.sstatic.net/3nsyy.jpg: fps=60, precision=10, speed=1).

The engine works the following way: the constant dt = 1000/(fps*precision/speed). Every particle then changes its speed and position linearly at the time period [t;t+dt]. Changing precision from 10 to 100 reduces the magnitude of the effect but makes everything run very slow and still doesn't slve the problem.

What have I done wrong while designing the engine? Are there any tricks to increase precision and avoid this problem?


Solution

  • I do not see how a static equilibrium is possible - at best, you will have a dynamic equilibrium of some sort. You have non-zero potential energy and nothing that causes damping (e.g., friction). With infinite precision, the particles will move around each other in a periodic pattern of some sort (e.g., orbit each other).

    Infinite-precision can't be done really on a computer, but floating-point precision is not likely to be the observed problem (though it will be, if you run the simulation long enough, anyway).

    I don't fully understand how you coded 'changes speed and position linearly' in your case. Note that you cannot simply assume that the force you computed at a given time t will remain constant until time t+dt and base your speed and position changes on this assumption. That might look easy in the sense that it allows you to apply your chosen force laws directly, but no matter how small your dt is, it is still finite - and making this assumption will introduce an error that is quite a bit larger than any errors caused by the FP approximation. Given initial positions and velocities at time t, to compute correctly the state at t+dt, you'd need (in the general case) to solve a differential equation. You cannot do a simple math of the kind acceleration = force / mass (because the force changes continuously as the body moves).