Exemplo n.º 1
0
 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);
 }
Exemplo n.º 2
0
        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;
            });
        }