/// <summary>
        /// Applies this force to a simulation.
        /// </summary>
        /// <param name="sim">the Simulation to apply the force to</param>
        public void Apply(Simulation sim)
        {
            foreach (var edge in sim.Springs)
            {
                var s = edge.p1;
                var t = edge.p2;
                dx = s.x - t.x;
                dy = s.y - t.y;
                dn = Math.Sqrt(dx * dx + dy * dy);
                dd = dn < 1.0 ? 1.0 : dn;

                k = edge.tension * (dn - edge.restLength);
                k += edge.damping * (dx * (s.vx - t.vx) + dy * (s.vy - t.vy)) / dd;
                k /= dd;

                Random rnd = new Random();
                if (dn == 0)
                {
                    dx = 0.01 * (0.5 - rnd.NextDouble());
                    dy = 0.01 * (0.5 - rnd.NextDouble());
                }

                fx = -k * dx;
                fy = -k * dy;

                s.fx += fx; s.fy += fy;
                t.fx -= fx; t.fy -= fy;
            }
        }
 /// <summary>
 /// Applies this force to a simulation.
 /// </summary>
 /// <param name="sim">the Simulation to apply the force to</param>
 public void Apply(Simulation sim)
 {
     if (_dc == 0) return;
     foreach (var particle in sim.Particles)
     {
         var p = particle;
         p.fx -= _dc * p.vx;
         p.fy -= _dc * p.vy;
     }
 }
        /// <summary>
        /// Applies this force to a simulation.
        /// </summary>
        /// <param name="sim">the Simulation to apply the force to</param>
        public void Apply(Simulation sim)
        {
            if (_gx == 0 && _gy == 0) return;

            foreach (var n in sim.Particles)
            {
                n.fx += _gx * n.mass;
                n.fy += _gy * n.mass;
            }
        }
        public Graph(IDictionary<string, string> initParams)
        {
            InitializeComponent();

            sim = new Simulation();
            particles = new Dictionary<string, Particle>();
            Loaded += new RoutedEventHandler(Graph_Loaded);

            string xml;
            if (initParams.TryGetValue("xml", out xml))
                LoadXML(initParams["xml"]);
        }
        private void bounds(Simulation graph)
        {
            double dx, dy;
            _x1 = _y1 = double.MaxValue;
            _x2 = _y2 = double.MinValue;

            // get bounding box
            foreach(var p in graph.Particles) {
                if (p.x < _x1) _x1 = p.x;
                if (p.y < _y1) _y1 = p.y;
                if (p.x > _x2) _x2 = p.x;
                if (p.y > _y2) _y2 = p.y;
            }

            // square the box
            dx = _x2 - _x1;
            dy = _y2 - _y1;
            if (dx > dy) {
                _y2 = _y1 + dx;
            } else {
                _x2 = _x1 + dy;
            }
        }
        /// <summary>
        /// Applies this force to a simulation.
        /// </summary>
        /// <param name="sim">the Simulation to apply the force to</param>
        public void Apply(Simulation sim)
        {
            if (_g == 0) return;

            // clear the quadtree
            clear(_root); _root = QuadTreeNode.Particle();

            // get the tree bounds
            bounds(sim);

            // populate the tree
            foreach (var particle in sim.Particles) {
                insert(particle, _root, _x1, _y1, _x2, _y2);
            }

            // traverse tree to compute mass
            accumulate(_root);

            // calculate forces on each Particle
            foreach (var particle in sim.Particles) {
                forces(particle, _root, _x1, _y1, _x2, _y2);
            }
        }