Example #1
0
        public ArborEdge addEdge(string srcSign, string tgtSign, double len = 1.0)
        {
            ArborNode src = this.getNode(srcSign);

            src = (src != null) ? src : this.addNode(srcSign);

            ArborNode tgt = this.getNode(tgtSign);

            tgt = (tgt != null) ? tgt : this.addNode(tgtSign);

            ArborEdge x = null;

            if (src != null && tgt != null)
            {
                foreach (ArborEdge edge in fEdges)
                {
                    if (edge.Source == src && edge.Target == tgt)
                    {
                        x = edge;
                        break;
                    }
                }
            }

            if (x == null)
            {
                x = new ArborEdge(src, tgt, len, ParamStiffness);
                fEdges.Add(x);
            }

            return(x);
        }
Example #2
0
 private static int getQuad(ArborNode i, Branch f)
 {
     try
     {
         if (i.Pt.exploded())
         {
             return(QNone);
         }
         ArborPoint h = i.Pt.sub(f.Origin);
         ArborPoint g = f.Size.div(2);
         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);
     }
 }
Example #3
0
        public ArborNode nearest(int sx, int sy)
        {
            ArborPoint x = this.fromScreen(sx, sy);

            ArborNode resNode = null;
            double    minDist = +1.0;

            foreach (ArborNode node in this.fNodes)
            {
                ArborPoint z = node.Pt;
                if (z.exploded())
                {
                    continue;
                }

                double dist = z.sub(x).magnitude();
                if (dist < minDist)
                {
                    resNode = node;
                    minDist = dist;
                }
            }

            //minDist = this.toScreen(resNode.Pt).sub(this.toScreen(x)).magnitude();
            return(resNode);
        }
Example #4
0
        public ArborViewer()
        {
            base.BorderStyle = BorderStyle.Fixed3D;
            base.TabStop     = true;
            base.BackColor   = Color.White;

            base.DoubleBuffered = true;
            base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            // repulsion - отталкивание, stiffness - тугоподвижность, friction - сила трения
            this.fSys = new ArborSystem(10000, 500 /*1000*/, 0.1, this);
            this.fSys.setScreenSize(this.Width, this.Height);
            this.fSys.AutoStop = false;

            this.fEnergyDebug = false;
            this.fDrawFont    = new Font("Calibri", 9);

            this.fStrFormat               = new StringFormat();
            this.fStrFormat.Alignment     = StringAlignment.Center;
            this.fStrFormat.LineAlignment = StringAlignment.Center;

            this.fBlackBrush    = new SolidBrush(Color.Black);
            this.fWhiteBrush    = new SolidBrush(Color.White);
            this.fDragged       = null;
            this.fNodesDragging = false;
        }
Example #5
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if (this.fNodesDragging && this.fDragged != null)
            {
                this.fDragged.Fixed = false;
                //this.fDragged.Mass = 1000;
                this.fDragged = null;
            }
        }
Example #6
0
        public RectangleF getNodeRect(Graphics gfx, ArborNode node)
        {
            SizeF      tsz = gfx.MeasureString(node.Sign, fDrawFont);
            float      w   = tsz.Width + 10;
            float      h   = tsz.Height + 4;
            ArborPoint pt  = fSys.toScreen(node.Pt);

            pt.X = Math.Floor(pt.X);
            pt.Y = Math.Floor(pt.Y);

            return(new RectangleF((float)pt.X - w / 2, (float)pt.Y - h / 2, w, h));
        }
Example #7
0
        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics gfx = pe.Graphics;

            try
            {
                gfx.SmoothingMode = SmoothingMode.AntiAlias;

                foreach (ArborNode node in fSys.Nodes)
                {
                    node.Box = this.getNodeRect(gfx, node);
                    gfx.FillRectangle(new SolidBrush(node.Color), node.Box);
                    gfx.DrawString(node.Sign, fDrawFont, this.fWhiteBrush, node.Box, this.fStrFormat);
                }

                using (Pen grayPen = new Pen(Color.Gray, 1))
                {
                    grayPen.StartCap = LineCap.NoAnchor;
                    grayPen.EndCap   = LineCap.ArrowAnchor;

                    foreach (ArborEdge edge in fSys.Edges)
                    {
                        ArborNode srcNode = edge.Source;
                        ArborNode tgtNode = edge.Target;

                        ArborPoint pt1 = fSys.toScreen(srcNode.Pt);
                        ArborPoint pt2 = fSys.toScreen(tgtNode.Pt);

                        ArborPoint tail = intersect_line_box(pt1, pt2, srcNode.Box);
                        ArborPoint head = (tail.isNull()) ? ArborPoint.Null : intersect_line_box(tail, pt2, tgtNode.Box);

                        if (!head.isNull() && !tail.isNull())
                        {
                            gfx.DrawLine(grayPen, (int)tail.X, (int)tail.Y, (int)head.X, (int)head.Y);
                        }
                    }
                }

                if (this.fEnergyDebug)
                {
                    string energy = "max=" + fSys.EnergyMax.ToString("0.00000") + ", mean=" + fSys.EnergyMean.ToString("0.00000");
                    gfx.DrawString(energy, fDrawFont, this.fBlackBrush, 10, 10);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("ArborViewer.OnPaint(): " + ex.Message);
            }
        }
Example #8
0
        public ArborNode addNode(string sign, double x, double y)
        {
            ArborNode node = this.getNode(sign);

            if (node != null)
            {
                return(node);
            }

            node    = new ArborNode(sign);
            node.Pt = new ArborPoint(x, y);

            fNames.Add(sign, node);
            fNodes.Add(node);

            return(node);
        }
Example #9
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!this.Focused)
            {
                base.Focus();
            }

            if (this.fNodesDragging)
            {
                this.fDragged = fSys.nearest(e.X, e.Y);

                if (this.fDragged != null)
                {
                    this.fDragged.Fixed = true;
                }
            }
        }
Example #10
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);
            }
        }
Example #11
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);
            }
        }
Example #12
0
 protected virtual ArborEdge CreateEdge(ArborNode src, ArborNode tgt, double len, double stiffness, bool directed = false)
 {
     return(new ArborEdge(src, tgt, len, stiffness, directed));
 }