Пример #1
0
        private void applySprings()
        {
            foreach (ArborEdge edge in fEdges)
            {
                ArborPoint s    = edge.Target.Pt.sub(edge.Source.Pt);
                double     sMag = s.magnitude();

                ArborPoint r = ((sMag > 0) ? s : ArborPoint.newRnd(1)).normalize();
                double     q = edge.Stiffness * (edge.Length - sMag);

                edge.Source.applyForce(r.mul(q * -0.5));
                edge.Target.applyForce(r.mul(q * 0.5));
            }
        }
Пример #2
0
        private void updateVelocityAndPosition(double dt)
        {
            int size = fNodes.Count;

            if (size == 0)
            {
                EnergySum  = 0;
                EnergyMax  = 0;
                EnergyMean = 0;
                return;
            }

            double eSum = 0;
            double eMax = 0;

            // calc center drift
            ArborPoint rr = new ArborPoint(0, 0);

            foreach (ArborNode node in fNodes)
            {
                rr = rr.sub(node.Pt);
            }
            ArborPoint drift = rr.div(size);

            // main updates loop
            foreach (ArborNode node in fNodes)
            {
                // apply center drift
                node.applyForce(drift);

                // apply center gravity
                if (ParamGravity)
                {
                    ArborPoint q = node.Pt.mul(-1);
                    node.applyForce(q.mul(ParamRepulsion / 100));
                }

                // update velocities
                if (node.Fixed)
                {
                    node.V = new ArborPoint(0, 0);
                }
                else
                {
                    node.V = node.V.add(node.F.mul(dt));
                    node.V = node.V.mul(1 - ParamFriction);

                    double r = node.V.magnitudeSquare();
                    if (r > 1000000)
                    {
                        node.V = node.V.div(r);
                    }
                }

                node.F.X = node.F.Y = 0;

                // update positions
                node.Pt = node.Pt.add(node.V.mul(dt));

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

            EnergySum  = eSum;
            EnergyMax  = eMax;
            EnergyMean = eSum / size;
        }