private void ApplySprings() { for (int i = 0, edgesCount = fEdges.Count; i < edgesCount; i++) { ArborEdge edge = fEdges[i]; ArborPoint s = edge.Target.Pt.Sub(edge.Source.Pt); ArborPoint r = s.Normalize(); double q = edge.Stiffness * (edge.Length - s.Magnitude()); edge.Source.ApplyForce(r.Mul(q * -0.5f)); edge.Target.ApplyForce(r.Mul(q * 0.5f)); } }
public void Test_Mul() { var pt = new ArborPoint(3, 4); Assert.AreEqual(3.0f, pt.X); Assert.AreEqual(4.0f, pt.Y); pt = pt.Mul(5); Assert.AreEqual(15.0f, pt.X); Assert.AreEqual(20.0f, pt.Y); }
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; }