1#include "GraphAutoLayout.h"
4GraphAutoLayout::GraphAutoLayout() {}
6GraphAutoLayout::~GraphAutoLayout() {}
8GraphAutoLayout::GraphAutoLayout(std::vector<ParseMatpower::BusData*> busData,
9 std::vector<ParseMatpower::BranchData*> branchData)
12 m_branchData = branchData;
13 for(
auto it = m_busData.begin(); it != m_busData.end(); ++it) {
15 m_nodes.push_back(node);
17 for(
auto it = m_branchData.begin(); it != m_branchData.end(); ++it) {
20 if(branch->
tap > 1e-3) weight = 2.0;
25void GraphAutoLayout::AddLink(
size_t index1,
size_t index2,
float weight)
28 if(index1 == index2 || weight == 0.f) {
return; }
30 size_t maxIndex = std::max(index1, index2);
31 size_t nodesMaxIndex = m_nodes.size() - 1;
32 for(
size_t i = nodesMaxIndex; i < maxIndex; i++) {
34 m_nodes.push_back(node);
37 m_edges.push_back({.node1 = m_nodes[index1], .node2 = m_nodes[index2], .weight = weight});
40void GraphAutoLayout::Compute(
size_t iterations)
42 wxProgressDialog pbd(_(
"Importing..."), _(
"Initializing..."), iterations,
nullptr,
43 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH);
45 float nodesCount = m_nodes.size();
49 float da = 2.f * M_PI / nodesCount;
50 for(
auto node = m_nodes.begin(); node != m_nodes.end(); node++) {
51 node->position.x = nodesCount * std::cos(a);
52 node->position.y = nodesCount * std::sin(a);
57 float area = nodesCount;
58 float k2 = area / nodesCount;
61 for(
size_t i = 0; i < iterations; i++) {
64 float temperature = 1.f - i / (float)iterations;
65 temperature *= temperature;
68 for(
auto node1 = m_nodes.begin(); node1 != m_nodes.end(); node1++) {
69 node1->displacement = {0.f, 0.f};
70 for(
auto node2 = m_nodes.begin(); node2 != m_nodes.end(); node2++) {
71 float dx = node1->position.x - node2->position.x;
72 float dy = node1->position.y - node2->position.y;
74 float d2 = dx * dx + dy * dy;
75 float coefficient = k2 / d2;
76 node1->displacement.x += coefficient * dx;
77 node1->displacement.y += coefficient * dy;
83 for(
auto edge = m_edges.begin(); edge != m_edges.end(); edge++) {
84 float dx = edge->node1.position.x - edge->node2.position.x;
85 float dy = edge->node1.position.y - edge->node2.position.y;
86 float d2 = dx * dx + dy * dy;
87 float coefficient = sqrt(d2) / k * edge->weight;
88 edge->node1.displacement.x -= dx * coefficient;
89 edge->node1.displacement.y -= dy * coefficient;
90 edge->node2.displacement.x += dx * coefficient;
91 edge->node2.displacement.y += dy * coefficient;
96 for(
auto node = m_nodes.begin(); node != m_nodes.end(); node++) {
97 float d2 = node->displacement.x * node->displacement.x + node->displacement.y * node->displacement.y;
100 float coefficient = temperature / d;
101 node->displacement.x *= coefficient;
102 node->displacement.y *= coefficient;
107 node->position.x += node->displacement.x;
108 node->position.y += node->displacement.y;
111 if(!pbd.Update(i, wxString::Format(
"Iteration = %d", i))) {
112 pbd.Update(iterations);
118void GraphAutoLayout::CalculatePositions(
int iterations,
double scale)
122 for(
auto it = m_busData.begin(); it != m_busData.end(); ++it) {
123 (*it)->busPosition = wxPoint2DDouble(m_nodes[index].position.x * scale, m_nodes[index].position.y * scale);
std::pair< int, int > busConnections