Exemple #1
0
 public ArborPoint add(ArborPoint a)
 {
     return(new ArborPoint(this.X + a.X, this.Y + a.Y));
 }
Exemple #2
0
 public ArborPoint sub(ArborPoint a)
 {
     return(new ArborPoint(this.X - a.X, this.Y - a.Y));
 }
Exemple #3
0
 public BarnesHutTree(ArborPoint origin, ArborPoint h, double dist)
 {
     this.fDist = dist * dist;
     this.fRoot = new Branch(origin, h.sub(origin));
 }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
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;
        }
Exemple #7
0
 public PSBounds(ArborPoint leftTop, ArborPoint rightBottom)
 {
     this.LeftTop     = leftTop;
     this.RightBottom = rightBottom;
 }
Exemple #8
0
 internal void applyForce(ArborPoint a)
 {
     this.F = this.F.add(a.div(this.Mass));
 }
Exemple #9
0
        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)));
        }