Пример #1
0
 internal static int GetQuad(ArborNode node, Branch branch)
 {
     try {
         if (node.Pt.IsExploded())
         {
             return(QNone);
         }
         ArborPoint h = node.Pt.Sub(branch.Origin);
         ArborPoint g = branch.Size.Div(2.0f);
         if (h.Y < g.Y)
         {
             return((h.X < g.X) ? QNw : QNe);
         }
         else
         {
             return((h.X < g.X) ? QSw : QSe);
         }
     } catch (Exception ex) {
         Debug.WriteLine("BarnesHutTree.GetQuad(): " + ex.Message);
         return(QNone);
     }
 }
Пример #2
0
        public void Insert(ArborNode node)
        {
            try {
                Branch           branch = fRoot;
                List <ArborNode> gst    = new List <ArborNode>();
                gst.Add(node);
                while (gst.Count > 0)
                {
                    ArborNode h = gst[0];
                    gst.RemoveAt(0);

                    double m  = h.Mass;
                    int    qd = GetQuad(h, branch);
                    object fp = branch.Q[qd];

                    if (fp == null)
                    {
                        branch.Q[qd] = h;

                        branch.Mass += m;
                        branch.Pt    = branch.Pt.Add(h.Pt.Mul(m));
                    }
                    else
                    {
                        if (fp is Branch)
                        {
                            branch.Mass += m;
                            branch.Pt    = branch.Pt.Add(h.Pt.Mul(m));

                            branch = (Branch)fp;

                            gst.Insert(0, h);
                        }
                        else
                        {
                            ArborPoint l = branch.Size.Div(2);
                            ArborPoint n = branch.Origin;

                            if (qd == QSe || qd == QSw)
                            {
                                n.Y += l.Y;
                            }
                            if (qd == QNe || qd == QSe)
                            {
                                n.X += l.X;
                            }

                            ArborNode o = (ArborNode)fp;
                            fp           = new Branch(n, l);
                            branch.Q[qd] = fp;

                            branch.Mass = m;
                            branch.Pt   = h.Pt.Mul(m);

                            branch = (Branch)fp;

                            ArborPoint oPt = o.Pt;
                            if (oPt.X == h.Pt.X && oPt.Y == h.Pt.Y)
                            {
                                double lX = l.X * 0.08f;
                                double lY = l.Y * 0.08f;
                                oPt.X = Math.Min(n.X + l.X, Math.Max(n.X, oPt.X - lX / 2 + ArborSystem.GetRandom() * lX));
                                oPt.Y = Math.Min(n.Y + l.Y, Math.Max(n.Y, oPt.Y - lY / 2 + ArborSystem.GetRandom() * lY));
                                o.Pt  = oPt;
                            }

                            gst.Add(o);
                            gst.Insert(0, h);
                        }
                    }
                }
            } catch (Exception ex) {
                Debug.WriteLine("BarnesHutTree.Insert(): " + ex.Message);
            }
        }
Пример #3
0
 public BarnesHutTree(ArborPoint lt, ArborPoint rb, double dist)
 {
     fDist = dist;
     fRoot = new Branch(lt, rb.Sub(lt));
 }
Пример #4
0
        public static ArborPoint IntersectLineLine(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.0f)
            {
                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.0f || ua > 1.0f || ub < 0.0f || ub > 1.0f)
            {
                return(ArborPoint.Null);
            }

            return(new ArborPoint(p1.X + ua * (p2.X - p1.X), p1.Y + ua * (p2.Y - p1.Y)));
        }
Пример #5
0
        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;
        }
Пример #6
0
        public ArborNode AddNode(string sign)
        {
            ArborPoint pt = NewRandomPoint();

            return(AddNode(sign, pt));
        }
Пример #7
0
 public PSBounds(ArborPoint leftTop, ArborPoint rightBottom)
 {
     LeftTop     = leftTop;
     RightBottom = rightBottom;
 }
Пример #8
0
 internal void ApplyForce(ArborPoint a)
 {
     F = F.Add(a.Div(Mass));
 }