Теория пружин автоматической верстки графиков - PullRequest
6 голосов
/ 25 августа 2009

Я пытаюсь визуально позиционировать объекты, чтобы показать их отношения друг с другом. Похоже, что для автоматической разметки графика, алгоритм пружины будет соответствовать моим потребностям. Я хотел бы реализовать это в Silverlight с помощью C #, поэтому я ищу примеры кода или ссылки на хорошие объяснения теории. Любая помощь приветствуется

Ответы [ 2 ]

6 голосов
/ 25 августа 2009

Некоторое время назад я написал некоторый код для выполнения динамических макетов графиков с использованием C # и XNA (полный исходный код доступен по запросу).

Вот некоторые из важнейших функций:

        public void UpdateNodes()
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                Vector2 netForce = Vector2.Zero;
                foreach (Node otherNode in nodes)
                {
                    if (otherNode != nodes[i])
                    {
                        netForce += CoulombRepulsion(nodes[i], otherNode); //calculate repulsion for all nodes
                        if (nodes[i].links.Contains(otherNode))
                        {
                            netForce += HookeAttraction(nodes[i], otherNode); //only calc attraction for linked nodes
                        }
                    }
                }
                nodes[i].Velocity += netForce;
                nodes[i].Velocity *= .99f;
                nodes[i].Position += nodes[i].Velocity;
            }
        }


        public Vector2 HookeAttraction(Node node1, Node node2) //ON node1 BY node2
        {
            Vector2 direction = Vector2.Subtract(node2.Position, node1.Position);
            direction.Normalize();

            return hookeConst* node2.Mass * Vector2.Distance(node1.Position, node2.Position) * direction;
        }

        public Vector2 GravAttraction(Node node1, Node node2) //ON node1 BY node2
        {
            Vector2 direction = Vector2.Subtract(node2.Position, node1.Position);
            direction.Normalize();

            return gravConst * node2.Mass * Vector2.DistanceSquared(node1.Position, node2.Position) * direction;
        }

Выберите две константы в зависимости от того, насколько быстро вы хотите, чтобы график сходился. Я использовал это:

        private const float hookeConst = .000005f;
        private const float gravConst = .00000001f;

Этот код довольно понятен, но не стесняйтесь спрашивать, нужно ли вам что-нибудь. По сути, вызовите функцию UpdateNodes () в цикле, и ваш график сойдет с минимальным энергопотреблением.

1 голос
/ 25 августа 2009

Я не использовал ни одного из этих примеров, но я считаю, что они будут вам полезны.

Здесь также есть похожий (дублирующий?) Вопрос: Визуализация графика в Silverlight

...