示例#1
0
        public void ApplyForces(ArborNode m, double repulsion)
        {
            try {
                Queue <object> queue = new Queue <object>();

                queue.Enqueue(fRoot);
                while (queue.Count > 0)
                {
                    object obj = queue.Dequeue();
                    if (obj == null || obj == m)
                    {
                        continue;
                    }

                    ArborPoint ptx, k;
                    double     l, kMag, massx;

                    if (obj is ArborNode)
                    {
                        ArborNode node = (ArborNode)obj;
                        massx = node.Mass;
                        ptx   = node.Pt;

                        k    = m.Pt.Sub(ptx);
                        kMag = k.Magnitude();

                        l = Math.Max(1.0f, kMag);
                        m.ApplyForce(k.Normalize().Mul(repulsion * massx).Div(l * l));
                    }
                    else
                    {
                        Branch branch = (Branch)obj;
                        massx = branch.Mass;
                        ptx   = branch.Pt.Div(massx);

                        k    = m.Pt.Sub(ptx);
                        kMag = k.Magnitude();

                        double h = Math.Sqrt(branch.Size.X * branch.Size.Y);
                        if (h / kMag > fDist)
                        {
                            queue.Enqueue(branch.Q[QNe]);
                            queue.Enqueue(branch.Q[QNw]);
                            queue.Enqueue(branch.Q[QSe]);
                            queue.Enqueue(branch.Q[QSw]);
                        }
                        else
                        {
                            l = Math.Max(1.0f, kMag);
                            m.ApplyForce(k.Normalize().Mul(repulsion * massx).Div(l * l));
                        }
                    }
                }
            } catch (Exception ex) {
                Debug.WriteLine("BarnesHutTree.ApplyForces(): " + ex.Message);
            }
        }
示例#2
0
        public void Test_ApplyForce()
        {
            var node = new ArborNode("x");

            Assert.IsNotNull(node);

            #if DEBUG
            node.V = new ArborPoint(1.0f, 1.0f);
            node.F = new ArborPoint(3.0f, 4.0f);

            node.Mass = 2.0f;
            node.ApplyForce(new ArborPoint(3.0f, 3.0f));
            Assert.AreEqual(new ArborPoint(4.5f, 5.5f), node.F);

            node.Mass = 0.0d;
            node.ApplyForce(new ArborPoint(3.0f, 3.0f));
            Assert.AreEqual(new ArborPoint(double.PositiveInfinity, double.PositiveInfinity), node.F);
            #endif
        }
示例#3
0
        private void UpdateVelocityAndPosition(double dt)
        {
            int nodesCount = fNodes.Count;

            if (nodesCount == 0)
            {
                fEnergyMax  = 0.0f;
                fEnergyMean = 0.0f;
                fEnergySum  = 0.0f;
                return;
            }

            double eMax = 0.0f;
            double eSum = 0.0f;

            // calc center drift
            ArborPoint rr = ArborPoint.Zero;

            for (int i = 0; i < nodesCount; i++)
            {
                ArborNode node = fNodes[i];
                rr = rr.Sub(node.Pt);
            }
            ArborPoint drift = rr.Div(nodesCount);

            // main updates loop
            for (int i = 0; i < nodesCount; i++)
            {
                ArborNode node = fNodes[i];

                // apply center drift
                node.ApplyForce(drift);

                // apply center gravity
                if (fGravity)
                {
                    ArborPoint q = node.Pt.Mul(-1.0f);
                    node.ApplyForce(q.Mul(fRepulsion / 100.0f));
                }

                // update velocities
                if (node.Fixed)
                {
                    node.V = ArborPoint.Zero;
                }
                else
                {
                    node.V = node.V.Add(node.F.Mul(dt));
                    node.V = node.V.Mul(1.0f - fFriction);

                    double r = node.V.MagnitudeSquare();
                    if (r > 1000000.0f)
                    {
                        node.V = node.V.Div(r);
                    }
                }

                node.F = ArborPoint.Zero;

                // update positions
                node.Pt = node.Pt.Add(node.V.Mul(dt));

                // update energy
                double energy = node.V.MagnitudeSquare();
                eSum += energy;
                eMax  = Math.Max(energy, eMax);
            }

            fEnergyMax  = eMax;
            fEnergyMean = eSum / nodesCount;
            fEnergySum  = eSum;
        }