private void Collision(float elapsedSeconds)
{
const int cellRadius = (int) (D*GridMultiplier);
const float w0 = 0.5f;
const float η = 0.5f;
var h = new float[ParticleCount];
for (var i = 0; i < ParticleCount; ++i)
{
var ix = (int) (Particles[i].X*GridMultiplier);
var iy = (int) (Particles[i].Y*GridMultiplier);
var neighbors = new List<int>();
for (var dx = Math.Max(-cellRadius, -ix);
dx < Math.Min(cellRadius, _width*GridMultiplier - ix - 1);
++dx)
for (var dy = Math.Max(-cellRadius, -iy);
dy < Math.Min(cellRadius, _height*GridMultiplier - iy - 1);
++dy)
neighbors.AddRange(_grid[ix + dx, iy + dy]);
var wi = 0f;
foreach (var j in neighbors)
{
if (i <= j)
continue;
var dist = Vector2.Distance(Particles[i], Particles[j]);
if (dist > 0.1f)
continue;
var n = Particles[j] - Particles[i];
_w[i, j] += (1 - n.Length())/D;
wi += _w[i, j];
}
h[i] = Math.Max(0, (wi - w0)*η);
}
for (var i = 0; i < ParticleCount; ++i)
{
var ix = (int) (Particles[i].X*GridMultiplier);
var iy = (int) (Particles[i].Y*GridMultiplier);
var neighbors = new List<int>();
for (var dx = Math.Max(-cellRadius, -ix);
dx < Math.Min(cellRadius, _width*GridMultiplier - ix - 1);
++dx)
for (var dy = Math.Max(-cellRadius, -iy);
dy < Math.Min(cellRadius, _height*GridMultiplier - iy - 1);
++dy)
neighbors.AddRange(_grid[ix + dx, iy + dy]);
foreach (var j in neighbors)
{
Velocities[i] += elapsedSeconds*0.5f*(h[i] + h[j])*_w[i, j]*(Particles[i] - Particles[j]);
}
}
}