public ArborPoint add(ArborPoint a) { return(new ArborPoint(this.X + a.X, this.Y + a.Y)); }
public ArborPoint sub(ArborPoint a) { return(new ArborPoint(this.X - a.X, this.Y - a.Y)); }
public BarnesHutTree(ArborPoint origin, ArborPoint h, double dist) { this.fDist = dist * dist; this.fRoot = new Branch(origin, h.sub(origin)); }
public void insert(ArborNode j) { try { Branch f = fRoot; List <ArborNode> gst = new List <ArborNode>(); gst.Add(j); while (gst.Count > 0) { ArborNode h = gst[0]; gst.RemoveAt(0); double m = h.Mass; int qd = getQuad(h, f); object fp = f.Q[qd]; if (fp == null) { f.Q[qd] = h; f.Mass += m; f.Pt = f.Pt.add(h.Pt.mul(m)); } else { if (fp is Branch) { f.Mass += m; f.Pt = f.Pt.add(h.Pt.mul(m)); f = fp as Branch; gst.Insert(0, h); } else { ArborPoint l = f.Size.div(2); ArborPoint n = new ArborPoint(f.Origin.X, f.Origin.Y); if (qd == QSe || qd == QSw) { n.Y += l.Y; } if (qd == QNe || qd == QSe) { n.X += l.X; } ArborNode o = fp as ArborNode; fp = new Branch(n, l); f.Q[qd] = fp; f.Mass = m; f.Pt = h.Pt.mul(m); f = fp as Branch; if (o.Pt.X == h.Pt.X && o.Pt.Y == h.Pt.Y) { double k = l.X * 0.08; double i = l.Y * 0.08; o.Pt.X = Math.Min(n.X + l.X, Math.Max(n.X, o.Pt.X - k / 2 + ArborSystem.NextRndDouble() * k)); o.Pt.Y = Math.Min(n.Y + l.Y, Math.Max(n.Y, o.Pt.Y - i / 2 + ArborSystem.NextRndDouble() * i)); } gst.Add(o); gst.Insert(0, h); } } } } catch (Exception ex) { Debug.WriteLine("BarnesHutTree.insert(): " + ex.Message); } }
public void applyForces(ArborNode m, double g) { try { Queue <object> f = new Queue <object>(); f.Enqueue(fRoot); while (f.Count > 0) { object obj = f.Dequeue(); if (obj == null || obj == m) { continue; } ArborPoint ptx, i, k; double l, kMag, massx; if (obj is ArborNode) { ArborNode node = (obj as ArborNode); massx = node.Mass; ptx = node.Pt; k = m.Pt.sub(ptx); kMag = k.magnitudeSquare(); i = ((kMag > 0) ? k : ArborPoint.newRnd(1)).normalize(); l = Math.Max(1, kMag); m.applyForce(i.mul(g * massx).div(l)); } else { Branch branch = (obj as Branch); massx = branch.Mass; ptx = branch.Pt.div(massx); k = m.Pt.sub(ptx); kMag = k.magnitudeSquare(); double h = branch.Size.X * branch.Size.Y; if (h / kMag > fDist) { f.Enqueue(branch.Q[QNe]); f.Enqueue(branch.Q[QNw]); f.Enqueue(branch.Q[QSe]); f.Enqueue(branch.Q[QSw]); } else { i = ((kMag > 0) ? k : ArborPoint.newRnd(1)).normalize(); l = Math.Max(1, kMag); m.applyForce(i.mul(g * massx).div(l)); } } } } catch (Exception ex) { Debug.WriteLine("BarnesHutTree.applyForces(): " + ex.Message); } }
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; }
public PSBounds(ArborPoint leftTop, ArborPoint rightBottom) { this.LeftTop = leftTop; this.RightBottom = rightBottom; }
internal void applyForce(ArborPoint a) { this.F = this.F.add(a.div(this.Mass)); }
public static ArborPoint intersect_line_line(ArborPoint p1, ArborPoint p2, ArborPoint p3, ArborPoint p4) { double denom = ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); if (denom == 0) { return(ArborPoint.Null); // lines are parallel } double ua = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / denom; double ub = ((p2.X - p1.X) * (p1.Y - p3.Y) - (p2.Y - p1.Y) * (p1.X - p3.X)) / denom; if (ua < 0 || ua > 1 || ub < 0 || ub > 1) { return(ArborPoint.Null); } return(new ArborPoint(p1.X + ua * (p2.X - p1.X), p1.Y + ua * (p2.Y - p1.Y))); }