Пример #1
0
        /// <summary>
        /// Initializes the positions of the vertices. Assign a random position inside the 'bounding box' to the vertices without positions.
        /// It does NOT modify the position of the other vertices.
        ///
        /// It generates an <code>IterationEnded</code> event.
        ///
        /// Bounding box:
        /// x coordinates: double.Epsilon - <code>width</code>
        /// y coordinates: double.Epsilon - <code>height</code>
        /// </summary>
        /// <param name="width">Width of the bounding box.</param>
        /// <param name="height">Height of the bounding box.</param>
        /// <param name="translate_x">Translates the generated x coordinate.</param>
        /// <param name="translate_y">Translates the generated y coordinate.</param>
        protected virtual void InitializeWithRandomPositions(double width, double height, double translate_x, double translate_y)
        {
            var rnd = new Random(Parameters.Seed);

            //initialize with random position
            foreach (TVertex v in VisitedGraph.Vertices)
            {
                //for vertices without assigned position
                if (!VertexPositions.ContainsKey(v))
                {
                    if (EnsureUniqueRandomInitialPositions)
                    {
                        Point newPoint;
                        do
                        {
                            newPoint =
                                new Point(
                                    Math.Max(double.Epsilon, rnd.NextDouble() * width + translate_x),
                                    Math.Max(double.Epsilon, rnd.NextDouble() * height + translate_y));
                        } while (VertexPositions.Values.Contains(newPoint));
                        VertexPositions[v] = newPoint;
                    }
                    else
                    {
                        VertexPositions[v] =
                            new Point(
                                Math.Max(double.Epsilon, rnd.NextDouble() * width + translate_x),
                                Math.Max(double.Epsilon, rnd.NextDouble() * height + translate_y));
                    }
                }
            }
        }
Пример #2
0
        public override void Compute(CancellationToken cancellationToken)
        {
            if (VisitedGraph.VertexCount == 1)
            {
                if (!VertexPositions.ContainsKey(VisitedGraph.Vertices.First()))
                {
                    VertexPositions.Add(VisitedGraph.Vertices.First(), new Point(0, 0));
                }
                return;
            }

            //initialize vertex positions
            InitializeWithRandomPositions(Parameters.Width, Parameters.Height);

            //initialize ISOM data
            foreach (var vertex in VisitedGraph.Vertices)
            {
                ISOMData isomData;
                if (!_isomDataDict.TryGetValue(vertex, out isomData))
                {
                    isomData = new ISOMData();
                    _isomDataDict[vertex] = isomData;
                }
            }

            _radius = Parameters.InitialRadius;
            var rnd = new Random(Parameters.Seed);

            for (var epoch = 0; epoch < Parameters.MaxEpoch; epoch++)
            {
                cancellationToken.ThrowIfCancellationRequested();

                Adjust(cancellationToken, rnd);

                //Update Parameters
                var factor = Math.Exp(-1 * Parameters.CoolingFactor * (1.0 * epoch / Parameters.MaxEpoch));
                _adaptation = Math.Max(Parameters.MinAdaption, factor * Parameters.InitialAdaption);
                if (_radius > Parameters.MinRadius && epoch % Parameters.RadiusConstantTime == 0)
                {
                    _radius--;
                }

                //report

                /*if ( ReportOnIterationEndNeeded )
                 *      OnIterationEnded( epoch, (double)epoch / (double)Parameters.MaxEpoch, "Iteration " + epoch + " finished.", true );
                 * else if (ReportOnProgressChangedNeeded)
                 * OnProgressChanged( (double)epoch / (double)Parameters.MaxEpoch * 100 );*/
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes the positions of the vertices. Assign a random position inside the 'bounding box' to the vertices without positions.
        /// It does NOT modify the position of the other vertices.
        ///
        /// It generates an <code>IterationEnded</code> event.
        ///
        /// Bounding box:
        /// x coordinates: double.Epsilon - <code>width</code>
        /// y coordinates: double.Epsilon - <code>height</code>
        /// </summary>
        /// <param name="width">Width of the bounding box.</param>
        /// <param name="height">Height of the bounding box.</param>
        /// <param name="translate_x">Translates the generated x coordinate.</param>
        /// <param name="translate_y">Translates the generated y coordinate.</param>
        protected virtual void InitializeWithRandomPositions(double width, double height, double translate_x, double translate_y)
        {
            var rnd = new Random(DateTime.Now.Millisecond);

            //initialize with random position
            foreach (TVertex v in VisitedGraph.Vertices)
            {
                //for vertices without assigned position
                if (!VertexPositions.ContainsKey(v))
                {
                    VertexPositions[v] =
                        new Point(
                            Math.Max(double.Epsilon, rnd.NextDouble() * width + translate_x),
                            Math.Max(double.Epsilon, rnd.NextDouble() * height + translate_y));
                }
            }
        }
        protected override void InitializeWithRandomPositions(double width, double height, double translate_x, double translate_y)
        {
            var rnd = GetRandomWithCurrentSeed();

            //initialize with random position
            foreach (TVertex v in VisitedGraph.Vertices)
            {
                //for vertices without assigned position
                if (!VertexPositions.ContainsKey(v))
                {
                    VertexPositions[v] =
                        new Point(
                            Math.Max(double.Epsilon, rnd.NextDouble() * width + translate_x),
                            Math.Max(double.Epsilon, rnd.NextDouble() * height + translate_y));
                }
            }
        }
Пример #5
0
        public override void Compute(CancellationToken cancellationToken)
        {
            var groups   = _params.GroupParametersList.Select(a => a.GroupId).OrderByDescending(a => a).ToList();
            var listRect = new Dictionary <object, Rect>();

            foreach (var group in groups)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var groupId = group;
                var gp      = _params.GroupParametersList.First(a => a.GroupId == groupId);
                //get vertices of the same group
                //var vertices = new List<TVertex>();
                var vertices = VisitedGraph.Vertices.Where(a => a.GroupId == groupId).ToList();
                //skip processing if there are no vertices in this group
                if (vertices.Count == 0)
                {
                    continue;
                }
                //get edges between vertices in the same group
                var edges = VisitedGraph.Edges.Where(a => a.Source.GroupId == a.Target.GroupId && a.Target.GroupId == groupId).ToList();
                //create and compute graph for a group
                var graph = GenerateGroupGraph(vertices, edges);
                //inject custom vertex and edge set into existing algorithm
                gp.LayoutAlgorithm.ResetGraph(graph.Vertices, graph.Edges);

                //assign vertex sizes to internal algorithm if needed
                if (gp.LayoutAlgorithm.NeedVertexSizes)
                {
                    gp.LayoutAlgorithm.VertexSizes = VertexSizes.Where(a => a.Key.GroupId == groupId)
                                                     .ToDictionary(a => a.Key, b => b.Value);
                }
                gp.LayoutAlgorithm.Compute(cancellationToken);

                //Move vertices to bound box if layout algorithm don't use bounds
                if (gp.ZoneRectangle.HasValue && !gp.IsAlgorithmBounded)
                {
                    var offsetX = gp.ZoneRectangle.Value.X;
                    var offsetY = gp.ZoneRectangle.Value.Y;
                    gp.LayoutAlgorithm.VertexPositions.ForEach(a =>
                    {
                        a.Value.Offset(offsetX, offsetY);
                    });
                }

                //write results to global positions storage
                double?[] left   = { null };
                double?[] top    = { null };
                double?[] right  = { null };
                double?[] bottom = { null };
                gp.LayoutAlgorithm.VertexPositions.ForEach(a =>
                {
                    left[0]   = left[0].HasValue ? (a.Value.X < left[0] ? a.Value.X : left[0]) : a.Value.X;
                    var w     = a.Value.X + VertexSizes[a.Key].Width;
                    var h     = a.Value.Y + VertexSizes[a.Key].Height;
                    right[0]  = right[0].HasValue ? (w > right[0] ? w : right[0]) : w;
                    top[0]    = top[0].HasValue ? (a.Value.Y < top[0] ? a.Value.Y : top[0]) : a.Value.Y;
                    bottom[0] = bottom[0].HasValue ? (h > bottom[0] ? h : bottom[0]) : h;

                    if (VertexPositions.ContainsKey(a.Key))
                    {
                        VertexPositions[a.Key] = a.Value;
                    }
                    else
                    {
                        VertexPositions.Add(a.Key, a.Value);
                    }
                });
                if (_params.ArrangeGroups)
                {
                    if (left[0] == null)
                    {
                        left[0] = 0;
                    }
                    if (right[0] == null)
                    {
                        right[0] = 0;
                    }
                    if (top[0] == null)
                    {
                        top[0] = 0;
                    }
                    if (bottom[0] == null)
                    {
                        bottom[0] = 0;
                    }
                    listRect.Add(gp.GroupId, gp.ZoneRectangle ?? new Rect(new Point(left[0].Value, top[0].Value), new Point(right[0].Value, bottom[0].Value)));
                }
            }

            if (_params.ArrangeGroups)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var origList = listRect.ToDictionary(a => a.Key, a => a.Value);
                var ora      = _params != null && _params.OverlapRemovalAlgorithm != null ? _params.OverlapRemovalAlgorithm : new FSAAlgorithm <object>(listRect, new OverlapRemovalParameters {
                    HorizontalGap = 10, VerticalGap = 10
                });
                ora.Initialize(listRect);
                ora.Compute(cancellationToken);
                cancellationToken.ThrowIfCancellationRequested();
                ora.Rectangles.ForEach(a =>
                {
                    int group = (int)a.Key;
                    //_params.GroupParametersList.FirstOrDefault(b => b.GroupId == (int)a.Key).ZoneRectangle = origList[a.Key];
                    ArrangeRectangle(a.Value, group, origList[a.Key]);
                });
            }
        }
Пример #6
0
        private void EdgeRoutingTest(TEdge ctrl)
        {
            //bad edge data check
            if (ctrl.Source.ID == -1 || ctrl.Target.ID == -1)
            {
                throw new GX_InvalidDataException("SimpleEdgeRouting() -> You must assign unique ID for each vertex to use SimpleER algo!");
            }
            if (ctrl.Source.ID == ctrl.Target.ID || !VertexPositions.ContainsKey(ctrl.Target))
            {
                return;
            }

            var start_point = VertexPositions[ctrl.Source]; // new Point(GraphAreaBase.GetX(ctrl.Source), GraphAreaBase.GetY(ctrl.Source));
            var end_point   = VertexPositions[ctrl.Target]; // new Point(GraphAreaBase.GetX(ctrl.Target), GraphAreaBase.GetY(ctrl.Target));

            if (start_point == end_point)
            {
                return;
            }

            var originalSizes = getSizesCollection(ctrl, end_point);
            var CHECKLIST     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);
            var leftSIZES     = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(originalSizes);


            var tempList = new List <Point>();

            tempList.Add(start_point);

            bool HaveIntersections = true;

            //while we have some intersections - proceed
            while (HaveIntersections)
            {
                var cur_drawback = drawback_distance;
                while (true)
                {
                    var item = CHECKLIST.Keys.FirstOrDefault();
                    //set last route point as current start point
                    start_point = tempList.Last();
                    if (item == null)
                    {
                        //checked all vertices and no intersection was found - quit
                        HaveIntersections = false;
                        break;
                    }
                    else
                    {
                        var   r = originalSizes[item].Value;
                        Point checkpoint;
                        //check for intersection point. if none found - remove vertex from checklist
                        if (MathHelper.GetIntersectionPoint(r, start_point, end_point, out checkpoint) == -1)
                        {
                            CHECKLIST.Remove(item); continue;
                        }
                        var    main_vector = new Vector(end_point.X - start_point.X, end_point.Y - start_point.Y);
                        double X = 0; double Y = 0;
                        //calculate drawback X coordinate
                        if (start_point.X == checkpoint.X || Math.Abs(start_point.X - checkpoint.X) < cur_drawback)
                        {
                            X = start_point.X;
                        }
                        else if (start_point.X < checkpoint.X)
                        {
                            X = checkpoint.X - cur_drawback;
                        }
                        else
                        {
                            X = checkpoint.X + cur_drawback;
                        }
                        //calculate drawback Y coordinate
                        if (start_point.Y == checkpoint.Y || Math.Abs(start_point.Y - checkpoint.Y) < cur_drawback)
                        {
                            Y = start_point.Y;
                        }
                        else if (start_point.Y < checkpoint.Y)
                        {
                            Y = checkpoint.Y - cur_drawback;
                        }
                        else
                        {
                            Y = checkpoint.Y + cur_drawback;
                        }
                        //set drawback checkpoint
                        checkpoint = new Point(X, Y);
                        bool isStartPoint = checkpoint == start_point;

                        bool routeFound        = false;
                        bool viceversa         = false;
                        int  counter           = 1;
                        var  joint             = new Point();
                        bool?blocked_direction = null;
                        while (!routeFound)
                        {
                            //choose opposite vector side each cycle
                            var signedDistance = viceversa ? side_distance : -side_distance;
                            //get new point coordinate
                            joint = new Point(
                                checkpoint.X + signedDistance * counter * (main_vector.Y / main_vector.Length),
                                checkpoint.Y - signedDistance * counter * (main_vector.X / main_vector.Length));

                            //now check if new point is in some other vertex
                            var iresult      = false;
                            var forced_break = false;
                            foreach (var sz in originalSizes)
                            {
                                if (sz.Value.Value.Contains(joint))
                                {
                                    iresult = true;
                                    //block this side direction
                                    if (blocked_direction == null)
                                    {
                                        blocked_direction = viceversa;
                                    }
                                    else
                                    {
                                        //both sides blocked - need to drawback
                                        forced_break = true;
                                    }
                                    break;
                                }
                            }
                            if (forced_break)
                            {
                                break;
                            }

                            //get vector intersection if its ok
                            if (!iresult)
                            {
                                iresult = MathHelper.IsIntersected(r, joint, end_point);
                            }

                            //if no vector intersection - we've found it!
                            if (!iresult)
                            {
                                routeFound        = true;
                                blocked_direction = null;
                            }
                            else
                            {
                                //still have an intersection with current vertex
                                HaveIntersections = true;
                                //skip point search if too many attempts was made (bad logic hack)
                                if (counter > 300)
                                {
                                    break;
                                }
                                counter++;
                                //switch vector search side
                                if (blocked_direction == null || (blocked_direction == viceversa))
                                {
                                    viceversa = !viceversa;
                                }
                            }
                        }

                        //if blocked and this is not start point (nowhere to drawback) - then increase drawback distance
                        if (blocked_direction != null && !isStartPoint)
                        {
                            //search has been blocked - need to drawback
                            cur_drawback += drawback_distance;
                        }
                        else
                        {
                            //add new route point if we found it
                            // if(routeFound)
                            tempList.Add(joint);
                            leftSIZES.Remove(item);
                        }
                    }
                    //remove currently evaded obstacle vertex from the checklist
                    CHECKLIST.Remove(item);
                }
                //assign possible left vertices as a new checklist if any intersections was found
                if (HaveIntersections)
                {
                    CHECKLIST = new Dictionary <TVertex, KeyValuePair <TVertex, Rect> >(leftSIZES);
                }
            }
            //finally, add an end route point

            tempList.Add(end_point);


            if (EdgeRoutes.ContainsKey(ctrl))
            {
                EdgeRoutes[ctrl] = tempList.Count > 2 ? tempList.ToArray() : null;
            }
            else
            {
                EdgeRoutes.Add(ctrl, tempList.Count > 2 ? tempList.ToArray() : null);
            }
        }