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)); } }
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; }