public ArborPoint GetViewCoords(ArborPoint pt) { if (fViewBounds == null) { return(ArborPoint.Null); } ArborPoint vd = fViewBounds.RightBottom.Sub(fViewBounds.LeftTop); double x = Margins[3] + (pt.Sub(fViewBounds.LeftTop).Div(vd.X).X *(fViewWidth - (Margins[1] + Margins[3]))); double y = Margins[0] + (pt.Sub(fViewBounds.LeftTop).Div(vd.Y).Y *(fViewHeight - (Margins[0] + Margins[2]))); return(new ArborPoint(x, y)); }
public ArborNode GetNearestNode(int viewX, int viewY) { ArborPoint pt = GetModelCoords(viewX, viewY); ArborNode result = null; double minDist = +1.0f; for (int i = 0, nodesCount = fNodes.Count; i < nodesCount; i++) { ArborNode node = fNodes[i]; ArborPoint nodePt = node.Pt; if (nodePt.IsExploded()) { continue; } double dist = nodePt.Sub(pt).Magnitude(); if (dist < minDist) { result = node; minDist = dist; } } return(result); }
private ArborPoint NewRandomPoint() { ArborPoint lt = fGraphBounds.LeftTop; ArborPoint rb = fGraphBounds.RightBottom; ArborPoint dt = rb.Sub(lt); double x = lt.X + (dt.X * ArborSystem.GetRandom()); double y = lt.Y + (dt.Y * ArborSystem.GetRandom()); return(new ArborPoint(x, y)); }
public void Test_Sub() { var pt = new ArborPoint(3, 4); Assert.AreEqual(3.0f, pt.X); Assert.AreEqual(4.0f, pt.Y); pt = pt.Sub(new ArborPoint(10, 11)); Assert.AreEqual(-7.0f, pt.X); Assert.AreEqual(-7.0f, pt.Y); }
private void UpdateGraphBounds() { ArborPoint lt = new ArborPoint(-1.0f, -1.0f); ArborPoint rb = new ArborPoint(+1.0f, +1.0f); for (int i = 0, nodesCount = fNodes.Count; i < nodesCount; i++) { ArborPoint pt = fNodes[i].Pt; if (pt.IsExploded()) { continue; } if (pt.X < lt.X) { lt.X = pt.X; } if (pt.Y < lt.Y) { lt.Y = pt.Y; } if (pt.X > rb.X) { rb.X = pt.X; } if (pt.Y > rb.Y) { rb.Y = pt.Y; } } lt.X -= 1.2f; lt.Y -= 1.2f; rb.X += 1.2f; rb.Y += 1.2f; ArborPoint sz = rb.Sub(lt); ArborPoint cent = lt.Add(sz.Div(2.0f)); ArborPoint d = new ArborPoint(Math.Max(sz.X, 4.0f), Math.Max(sz.Y, 4.0f)).Div(2.0f); fGraphBounds = new PSBounds(cent.Sub(d), cent.Add(d)); fBHTree = new BarnesHutTree(fGraphBounds.LeftTop, fGraphBounds.RightBottom, Theta); }
public BarnesHutTree(ArborPoint lt, ArborPoint rb, double dist) { fDist = dist; fRoot = new Branch(lt, rb.Sub(lt)); }
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; }