示例#1
0
        private double calcAngularWidth(Representation.node n, int d)
        {
            Pars[n.name].visited = true;
            if (d > m_maxDepth)
            {
                m_maxDepth = d;
            }
            double aw = 0;
            double w = n.DisplayShape.Width, h = n.DisplayShape.Height;
            double diameter = d == 0 ? 0 : Math.Sqrt(w * w + h * h) / d;

            if ((n.arcs.Count > 1) || (n == root))
            {
                foreach (Representation.arc a in n.arcs)
                {
                    if (!Pars[a.otherNode(n).name].visited)
                    {
                        aw += calcAngularWidth(a.otherNode(n), d + 1);
                    }
                }
                aw = Math.Max(diameter, aw);
            }
            else
            {
                aw = diameter;
            }
            Pars[n.name].width = aw;
            return(aw);
        }
示例#2
0
        private List <Representation.node> sortedChildren(Representation.node n, Representation.node p)
        {
            double basevalue = 0;
            int    cc;

            // update basevalue angle for node ordering

            if (p != null)
            {
                cc        = n.arcs.Count - 1;
                basevalue = normalize(Math.Atan2(p.Y - n.Y, p.X - n.X));
            }
            else
            {
                cc = n.arcs.Count;
            }

            if ((cc == 0) && (n != root))
            {
                return(null);
            }

            Representation.arc  arc0 = (Representation.arc)n.arcs[0];
            Representation.node c    = arc0.otherNode(n);

            if (c == p)
            {
                Representation.arc arc1 = (Representation.arc)n.arcs[1];
                c = arc1.otherNode(n);
            }

            double[] angle = new double[n.arcs.Count];
            int[]    idx   = new int[n.arcs.Count];
            for (int i = 0; i < n.arcs.Count; ++i)
            {
                Representation.arc arc = (Representation.arc)n.arcs[i];
                c      = arc.otherNode(n);
                idx[i] = i;
                if (c != p)
                {
                    angle[i] = normalize(-basevalue + Math.Atan2(c.Y - n.Y, c.X - n.X));
                }

                else
                {
                    angle[i] = Double.MaxValue;
                }
            }
            Array.Sort(angle, idx); //or is it the other way around?
            List <Representation.node> col = new List <Representation.node>();

            //List<node> children = n.Children;
            for (int i = 0; i < cc; ++i)
            {
                Representation.arc arc = (Representation.arc)n.arcs[idx[i]];
                col.Add(arc.otherNode(n));
            }
            return(col);
        }
示例#3
0
 protected void setPolarLocation(Representation.node n, Representation.node p, double r, double t)
 {
     for (int i = 0; i < graph.nodes.Count; i++)
     {
         if (graph.nodes[i].name == n.name)
         {
             graph.nodes[i].X = (float)(m_origin.X + r * Math.Cos(t));
             graph.nodes[i].Y = (float)(m_origin.Y + r * Math.Sin(t));
         }
     }
 }
示例#4
0
 private void AdjustChildren(Representation.node v, BalloonData data, float s)
 {
     if (s > Math.PI)
     {
         data.c = (float)Math.PI / s;
         data.f = 0;
     }
     else
     {
         data.c = 1;
         data.f = (float)Math.PI - s;
     }
 }
示例#5
0
        private void calcAngularBounds(Representation.node r, Representation.node ParentNode)
        {
            if (m_prevRoot == null || r == m_prevRoot)
            {
                m_prevRoot = r;
                return;
            }

            // try to find previous parent of root
            Representation.node p = m_prevRoot;
            while (true)
            {
                Representation.node pp = ParentNode;
                if (pp == r)
                {
                    break;
                }
                else if (pp == null)
                {
                    m_prevRoot = r;
                    return;
                }
                p = pp;
            }

            // compute offset due to children's angular width
            double dt = 0;
            List <Representation.node> iter = sortedChildren(r, ParentNode);

            foreach (Representation.node n in iter)
            {
                if (n == p)
                {
                    break;
                }
                dt += Pars[n.name].width;
            }
            double rw = Pars[r.name].width;
            double pw = Pars[p.name].width;

            dt = -Math.PI * 2 * (dt + pw / 2) / rw;

            // set angular bounds
            m_theta1   = dt + Math.Atan2(p.Y - r.Y, p.X - r.X);
            m_theta2   = m_theta1 + Math.PI * 2;
            m_prevRoot = r;
        }
示例#6
0
        /// <summary>
        /// Finds the the closest vertex to the given position.
        /// </summary>
        /// <param name="tempPos">The position.</param>
        /// <returns>Returns with the reference of the closest vertex.</returns>
        private Representation.node GetClosest(Point tempPos)
        {
            Representation.node vertex = default(Representation.node);
            double distance            = double.MaxValue;

            //find the closest vertex

            for (var i = 0; i < nodeList.Count; i++)
            {
                Point  nodeLocation = new Point(nodeList[i].X, nodeList[i].Y);
                double d            = (tempPos - nodeLocation).Length;
                if (d < distance)
                {
                    vertex   = nodeList[i];
                    distance = d;
                }
            }
            return(vertex);
        }
示例#7
0
 protected int num_descendents(Representation.node node)
 {
     if (node.arcsFrom.Count == 0)
     {
         return(0);
     }
     else if (node.arcsFrom.Count == 1)
     {
         return(num_descendents(node.arcsFrom[0].To));
     }
     else
     {
         var total_desc_count = 0;
         for (int i = 0; i < node.arcsFrom.Count; i++)
         {
             total_desc_count += num_descendents(node.arcsFrom[i].To);
         }
         return(node.arcsFrom.Count + total_desc_count);
     }
 }
示例#8
0
        protected void outputchild(Representation.node node, int x_val, int y_val)
        {
            node.X = x_val;
            node.Y = y_val;
            var x_offset = 0;

            for (int i = 0; i < node.arcsFrom.Count; i++)
            {
                if (i > 0)
                {
                    if (num_descendents(node.arcsFrom[i - 1].To) > 0)
                    {
                        x_offset += (int)HorizontalSpacing * (num_descendents(node.arcsFrom[i - 1].To) - 1);
                    }
                }

                outputchild(node.arcsFrom[i].To, (x_val + x_offset), (y_val + (int)VerticalSpacing));
                x_offset = x_offset + (int)HorizontalSpacing;
            }
        }
示例#9
0
        private void SecondWalk(Representation.node v, Representation.node r, double x, double y, float l, float t)
        {
            visitedVertices.Add(v);
            BalloonData data = datas[v];

            for (var i = 0; i < graph.nodes.Count; i++)
            {
                if (graph.nodes[i].name == v.name)
                {
                    graph.nodes[i].X = x * HorizontalSpacing;
                    graph.nodes[i].Y = y * VerticalSpacing;
                }
            }

            float dd     = l * data.d;
            float p      = (float)(t + Math.PI);
            int   degree = v.degree;
            float fs     = (degree == 0 ? 0 : data.f / degree);
            float pr     = 0;

            foreach (var edge in v.arcsFrom)
            {
                var otherVertex = edge.To;
                if (visitedVertices.Contains(otherVertex))
                {
                    continue;
                }

                var   otherData = datas[otherVertex];
                float aa        = data.c * otherData.a;
                float rr        = (float)(data.d * Math.Tan(aa) / (1 - Math.Tan(aa)));
                p += pr + aa + fs;

                float xx = (float)((l * rr + dd) * Math.Cos(p));
                float yy = (float)((l * rr + dd) * Math.Sign(p));
                pr = aa;;
                SecondWalk(otherVertex, v, x + xx, y + yy, l * data.c, p);
            }
        }
示例#10
0
        protected void  Adjust()
        {
            _tempPos = new Point();
            //get a random point in the container
            _tempPos.X = 0.1 * (HorizontalSpacing * 9) + (_rnd.NextDouble() * 0.8 * (HorizontalSpacing * 9));
            _tempPos.Y = 0.1 * (VerticalSpacing * 9) + (_rnd.NextDouble() * 0.8 * (VerticalSpacing * 9));

            //find the closest vertex to this random point
            Representation.node closest = GetClosest(_tempPos);

            //adjust the vertices to the selected vertex
            for (var i = 0; i < nodeList.Count; i++)
            {
                if (_isomDataDict.Keys.Contains(nodeList[i]))
                {
                    ISOMData vid = _isomDataDict[nodeList[i]];
                    vid.Distance = 0;
                    vid.Visited  = false;
                }
            }
            AdjustVertex(closest);
        }
示例#11
0
        protected void layout(Representation.node n, double r, double theta1, double theta2, Representation.node ParentNode)
        {
            Pars[n.name].visited = true;
            double dtheta = (theta2 - theta1);
            double dtheta2 = dtheta / 2.0;
            double width = Pars[n.name].width;
            double cfrac, nfrac = 0.0;

            foreach (Representation.node c in sortedChildren(n, ParentNode))
            {
                Params cp = Pars[c.name];
                cfrac = cp.width / width;
                if (!Pars[c.name].visited && ((c.arcs.Count > 1) || (c == root)))
                {
                    layout(c, r + m_radiusInc,
                           theta1 + nfrac * dtheta, theta1 + (nfrac + cfrac) * dtheta,
                           n);
                }
                setPolarLocation(c, n, r, theta1 + nfrac * dtheta + cfrac * dtheta2);
                cp.angle = cfrac * dtheta;
                nfrac   += cfrac;
            }
        }
示例#12
0
        private void FirstWalk(Representation.node v)
        {
            var data = datas[v];

            visitedVertices.Add(v);
            data.d = 0;
            float s = 0;

            foreach (var edge in v.arcsFrom)
            {
                var otherVertex = edge.To;
                var otherData   = datas[otherVertex];

                if (!visitedVertices.Contains(otherVertex))
                {
                    FirstWalk(otherVertex);
                    data.d      = Math.Max(data.d, otherData.r);
                    otherData.a = (float)Math.Atan(((float)otherData.r) / (data.d + otherData.r));
                    s          += otherData.a;
                }
            }
            AdjustChildren(v, data, s);
            SetRadius(v, data);
        }
示例#13
0
 private void SetRadius(Representation.node v, BalloonData data)
 {
     data.r = (int)Math.Max(data.d / 2, minRadius);
 }
示例#14
0
        protected override bool RunLayout()
        {
            bool istree = FindRoot();

            if (istree == false)
            {
                backgroundWorker.ReportProgress(100);
                throw new Exception("The input graph is not a tree. This layout only works on tree structures.");
            }


            backgroundWorker.ReportProgress(25);
            if (backgroundWorker.CancellationPending)
            {
                return(false);
            }

            m_origin.X = 0;
            m_origin.Y = 0;
            int minNumArcsFrom = int.MaxValue;
            int rootIndex      = 0;

            int[] numArcsFrom = new int[graph.nodes.Count];
            for (int i = 0; i != graph.nodes.Count; i++)
            {
                numArcsFrom[i] = graph.nodes[i].arcsFrom.Count;
                if (numArcsFrom[i] < minNumArcsFrom)
                {
                    minNumArcsFrom = numArcsFrom[i];
                    rootIndex      = i;
                }
            }

            backgroundWorker.ReportProgress(40);
            if (backgroundWorker.CancellationPending)
            {
                return(false);
            }
            root = graph.nodes[rootIndex];

            m_radiusInc = RadialInc;        //Make default radius the value of spacing slider
            m_prevRoot  = null;
            m_theta1    = 0;
            m_theta2    = m_theta1 + Math.PI * 2;
            Pars        = new Dictionary <string, Params>();
            Params par;

            foreach (Representation.node node in graph.nodes)
            {
                par = new Params();
                Pars.Add(node.name, par);
            }
            foreach (Params p in Pars.Values)
            {
                p.visited = false;
            }
            Representation.node n = root;
            Params np             = Pars[n.name];

            // calc relative widths and maximum tree depth
            // performs one pass over the tree
            m_maxDepth = 0;
            calcAngularWidth(n, 0);

            backgroundWorker.ReportProgress(50);
            if (backgroundWorker.CancellationPending)
            {
                return(false);
            }

            foreach (Params p in Pars.Values)
            {
                p.visited = false;
            }

            if (!m_setTheta)
            {
                calcAngularBounds(n, null);
            }

            // perform the layout
            if (m_maxDepth > 0)
            {
                layout(n, m_radiusInc, m_theta1, m_theta2, null);
            }

            // update properties of the root node
            for (int i = 0; i < graph.nodes.Count; i++)
            {
                if (graph.nodes[i].name == n.name)
                {
                    graph.nodes[i].X = m_origin.X;
                    graph.nodes[i].Y = m_origin.Y;
                }
            }

            backgroundWorker.ReportProgress(90);
            if (backgroundWorker.CancellationPending)
            {
                return(false);
            }
            np.angle = m_theta2 - m_theta1;
            return(true);
        }
示例#15
0
        private void AdjustVertex(Representation.node closest)
        {
            if (_isomDataDict.Keys.Contains(closest))
            {
                _queue.Clear();
                ISOMData vid = _isomDataDict[closest];
                vid.Distance = 0;
                vid.Visited  = true;
                _queue.Enqueue(closest);
                while (_queue.Count > 0)
                {
                    if (_queue.Count != 0)
                    {
                        Representation.node current = _queue.Dequeue();
                        if (current != null)
                        {
                            ISOMData currentVid = _isomDataDict[current];

                            Point pos = VertexPositions[current];

                            Vector force  = _tempPos - pos;
                            double factor = adaptation / Math.Pow(2, currentVid.Distance);

                            pos += factor * force;
                            VertexPositions[current] = pos;

                            List <node> neighbors = new List <node>(GetNeighbors(current));

                            if (currentVid.Distance < radius)
                            {
                                for (int i = 0; i < neighbors.Count; i++)
                                {
                                    ISOMData nvid = _isomDataDict[neighbors[i]];
                                    if (!nvid.Visited)
                                    {
                                        nvid.Visited  = true;
                                        nvid.Distance = currentVid.Distance + 1;
                                        _queue.Enqueue(neighbors[i]);
                                    }
                                }
                            }

                            int index = 0;

                            /*
                             * for (int i = 0; graph.nodes[i] != current; i++)
                             * {
                             *  index++;
                             * }
                             *
                             * graph.nodes[index].X = VertexPositions[current].X;
                             * graph.nodes[index].Y = VertexPositions[current].Y;
                             */

                            //PORT VERTEXPOSITIONS TO graph.node (UPDATE LOCATIONS OF NODES)

                            foreach (Point point in VertexPositions.Values.ToList())
                            {
                                if (graph.nodes[index].name != null)
                                {
                                    if (graph.nodes[index].arcs != null)
                                    {
                                        if (point.X == double.NaN || point.Y == double.NaN)
                                        {
                                            return;
                                        }
                                        graph.nodes[index].X = point.X;
                                        graph.nodes[index].Y = point.Y;
                                        index++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }