public Ratchet.Collections.Quadtree <AgregatedParticle> CreateGrid() { Ratchet.Collections.Quadtree <AgregatedParticle> grid = new Ratchet.Collections.Quadtree <AgregatedParticle>(); for (int n = 0; n < _Swarm.Length; n++) { var node = grid.GetNode((long)_Swarm[n]._x, (long)_Swarm[n]._y, 1, 1); AgregatedParticle agregatedParticles = node.Element; if (agregatedParticles == null) { agregatedParticles = new AgregatedParticle(node.X + (float)node.Size / 2.0f, node.Y + (float)node.Size / 2.0f); node.Element = agregatedParticles; } else { agregatedParticles._weigth++; } } return(grid); }
public void Refresh() { Ratchet.Collections.Quadtree <AgregatedParticle> particles = CreateGrid(); Parallel.ForEach <Particle>(_Swarm, (Particle particle) => { float x = particle._x; float y = particle._y; float fx = 0; float fy = 0; foreach (Ratchet.Collections.Quadtree <AgregatedParticle> .Node neighboor in particles.GetNode((int)x - 15, (int)y - 15, 32, 32)) { if (neighboor.Element != null) { // Quick interaction it is not meant to be accurate just pretty :) float nx = neighboor.Element._x; float ny = neighboor.Element._y; int weight = neighboor.Element._weigth; float dx = (x - nx) * (x - nx); float dy = (y - ny) * (y - ny); // Dirty hack to not count self interaction if ((dx < float.Epsilon && dy < float.Epsilon)) { continue; } float d2 = (x - nx) * (x - nx) + (y - ny) * (y - ny); float d = (float)System.Math.Sqrt((double)d2); // Only look at particles in a small radius if (d > 30f) { continue; } float dirx = (float)(nx - x) / d; float diry = (float)(ny - y) / d; // Again a hack to avoid some instabilities if (d2 < 1.0f) { d2 = 1.0f; } float f = (0.02f * (float)weight) / d2; fx += dirx * f; fy += diry * f; } } particle._fx += fx; particle._fy += fy; particle._x += particle._fx; particle._y += particle._fy; }); }