private void InitAlgorithm()
        {
            vertices = new LinLogVertex[VisitedGraph.VertexCount];

            var vertexMap = new Dictionary <TVertex, LinLogVertex>();

            //vertexek indexelése
            int i = 0;

            foreach (TVertex v in VisitedGraph.Vertices)
            {
                vertices[i] = new LinLogVertex
                {
                    Index           = i,
                    OriginalVertex  = v,
                    Attractions     = new LinLogEdge[VisitedGraph.Degree(v)],
                    RepulsionWeight = 0,
                    Position        = VertexPositions[v]
                };
                vertexMap[v] = vertices[i];
                i++;
            }

            //minden vertex-hez felépíti az attractionWeights, attractionIndexes,
            //és a repulsionWeights struktúrát, valamint átmásolja a pozícióját a VertexPositions-ból
            foreach (var v in vertices)
            {
                int attrIndex = 0;
                foreach (var e in VisitedGraph.InEdges(v.OriginalVertex))
                {
                    double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.Source],
                        AttractionWeight = weight
                    };
                    //TODO look at this line below
                    //v.RepulsionWeight += weight;
                    v.RepulsionWeight += 1;
                    attrIndex++;
                }

                foreach (var e in VisitedGraph.OutEdges(v.OriginalVertex))
                {
                    double weight = e is WeightedEdge <TVertex>?((e as WeightedEdge <TVertex>).Weight) : 1;
                    v.Attractions[attrIndex] = new LinLogEdge
                    {
                        Target           = vertexMap[e.Target],
                        AttractionWeight = weight
                    };
                    //v.RepulsionWeight += weight;
                    v.RepulsionWeight += 1;
                    attrIndex++;
                }

                v.RepulsionWeight = Math.Max(v.RepulsionWeight, Parameters.gravitationMultiplier);
            }

            repulsionMultiplier = ComputeRepulsionMultiplier();
        }
        private void InitAlgorithm()
        {
            _vertices = new LinLogVertex[VisitedGraph.VertexCount];

            var verticesMap = new Dictionary <TVertex, LinLogVertex>();

            // Index vertices
            int i = 0;

            foreach (TVertex vertex in VisitedGraph.Vertices)
            {
                _vertices[i] = new LinLogVertex(i, vertex, new LinLogEdge[VisitedGraph.Degree(vertex)])
                {
                    RepulsionWeight = 0,
                    Position        = VerticesPositions[vertex]
                };
                verticesMap[vertex] = _vertices[i];
                ++i;
            }

            // Compute best attraction weight and attraction index for each vertex
            foreach (LinLogVertex vertex in _vertices)
            {
                int attractionIndex = 0;
                foreach (TEdge edge in VisitedGraph.InEdges(vertex.OriginalVertex))
                {
                    var    weightedEdge = edge as WeightedEdge <TVertex>;
                    double weight       = weightedEdge?.Weight ?? 1;
                    vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Source], weight);
                    // TODO update repulsion weight?
                    ++vertex.RepulsionWeight;
                    ++attractionIndex;
                }

                foreach (TEdge edge in VisitedGraph.OutEdges(vertex.OriginalVertex))
                {
                    var    weightedEdge = edge as WeightedEdge <TVertex>;
                    double weight       = weightedEdge?.Weight ?? 1;
                    vertex.Attractions[attractionIndex] = new LinLogEdge(verticesMap[edge.Target], weight);
                    ++vertex.RepulsionWeight;
                    ++attractionIndex;
                }

                vertex.RepulsionWeight = Math.Max(vertex.RepulsionWeight, Parameters.GravitationMultiplier);
            }

            _repulsionMultiplier = ComputeRepulsionMultiplier();
        }
 private void CountLeaves(TVertex parent, TVertex v)
 {
     if (VisitedGraph.Degree(v) == 1)
     {
         _leafCounts[v] = 1;
     }
     else
     {
         int count = 0;
         foreach (TEdge edge in GetEdges(v).Where(e => !e.OtherVertex(v).Equals(parent)))
         {
             TVertex child = edge.OtherVertex(v);
             CountLeaves(v, child);
             count += _leafCounts[child];
         }
         _leafCounts[v] = count;
     }
 }
        protected override void InternalCompute()
        {
            _leafCounts.Clear();
            CountLeaves(null, _root);

            double denom = 2 * Math.Tan(Math.PI / _leafCounts[_root]);

            TEdge[] edges  = VisitedGraph.Edges.Where(e => !(e is ILengthEdge <TVertex>) || ((ILengthEdge <TVertex>)e).Length > 0).ToArray();
            double  minLen = 0;

            if (edges.Length > 0)
            {
                minLen = edges.Min(e => e is ILengthEdge <TVertex>?((ILengthEdge <TVertex>)e).Length: 1);
            }
            double minSlope = minLen == 0 ? 0 : Parameters.MinimumLength / minLen;

            switch (Parameters.BranchLengthScaling)
            {
            case BranchLengthScaling.MinimizeLabelOverlapAverage:
                bool first = true;
                foreach (TVertex v in VisitedGraph.Vertices.Where(v => VisitedGraph.Degree(v) == 1))
                {
                    Size   sz         = _vertexSizes[v];
                    TEdge  edge       = GetEdges(v).First();
                    double x          = 1;
                    var    lengthEdge = edge as ILengthEdge <TVertex>;
                    if (lengthEdge != null)
                    {
                        x = lengthEdge.Length;
                    }
                    if (x <= 0.0)
                    {
                        continue;
                    }
                    double y     = sz.Height / denom;
                    double slope = y / x;
                    _slope = first ? slope : (_slope + slope) / 2;
                    first  = false;
                }
                _slope = Math.Max(minSlope, _slope);
                break;

            case BranchLengthScaling.MinimizeLabelOverlapMinimum:
                _slope = double.MaxValue;
                foreach (TVertex v in VisitedGraph.Vertices.Where(v => VisitedGraph.Degree(v) == 1))
                {
                    Size   sz         = _vertexSizes[v];
                    TEdge  edge       = GetEdges(v).First();
                    double x          = 1;
                    var    lengthEdge = edge as ILengthEdge <TVertex>;
                    if (lengthEdge != null)
                    {
                        x = lengthEdge.Length;
                    }
                    if (x <= 0.0)
                    {
                        continue;
                    }
                    double y = sz.Height / denom;
                    _slope = Math.Min(_slope, y / x);
                }
                _slope = Math.Max(minSlope, _slope);
                break;

            case BranchLengthScaling.FixedMinimumLength:
                _slope = minSlope;
                break;
            }

            VertexPositions[_root] = new Point(0, 0);
            CalcPositions(default(TEdge), _root, 2 * Math.PI, 0);
        }