void BalanceGraph::newProcessRegion(Region *region, Graph &graph) { // if we do not need to move the region if(region->getDforce() == 0) { return; } double minMovement = region->getDforce(); if(minMovement < 0) { minMovement = (-1)*minMovement; } for(Segment* s : region->segments) { for(AbstractNode* node : s->nodes) { int layer = node->getLayer(); int positionInLayer = node->getPositionInLayer(); // attempting to move to the left if(region->getDforce() < 0) { // If we are the leftmost node if(positionInLayer == 0) { continue; } AbstractNode* leftNode = graph.getLayers().at(layer).at(positionInLayer-1); // if leftNode is in the same region if(nodeToSegment.value(leftNode)->region == s->region) { continue; } double availableMovement = node->x() - (leftNode->x() + leftNode->boundingRect().width() + 10); if(availableMovement < minMovement) { minMovement = availableMovement; } } // Attempting to move to the right if(region->getDforce() > 0) { // if we are the rightmost in layer if(positionInLayer == graph.getLayers().at(layer).size()-1) { continue; } AbstractNode* rightNode = graph.getLayers().at(layer).at(positionInLayer+1); // if rightNode is in the same region if(nodeToSegment.value(rightNode)->region == s->region) { continue; } double availableMovement = rightNode->x() - (node->x() + node->boundingRect().width() + 10); if(availableMovement < minMovement) { minMovement = availableMovement; } } } } // Calculate the maximal movement // move the whole region for(Segment* s : region->segments) { for(AbstractNode* n : s->nodes) { // movement to the left if(region->getDforce() < 0) { n->moveBy(-minMovement,0); } else { n->moveBy(minMovement,0); } } } }
void BalanceGraph::newSweep(Graph &graph, BalanceGraph::direction direction) { if(direction == DOWN) { calculateDownForces(); } else { calculateUpForces(); } // Generate trivial regions QList<Region*> regions; for(Segment* segment : segments) { Region* region = new Region(); segment->region = region; region->minTopologicNumber = segment->topologicNumber; region->segments.append(segment); regions.append(region); } // Combine regions bool regionsChanged = true; while(regionsChanged) { regionsChanged = false; // Combine for(Segment* segment : segments) { for(AbstractNode* left : segment->nodes) { int layer = left->getLayer(); int positionOfLeft = left->getPositionInLayer(); // if we are last in the layer if(positionOfLeft == graph.getLayers().at(layer).size()-1) { continue; } AbstractNode* right = graph.getLayers().at(layer).at(positionOfLeft+1); Region* leftRegion = nodeToSegment.value(left)->region; Region* rightRegion = nodeToSegment.value(right)->region; // if we are the same region just continue if(leftRegion == rightRegion) { continue; } // we are touching another node if(right->x() <= (left->x() + 10 + left->boundingRect().width())) { // if we are about to walk into each other if(leftRegion->getDforce() >= rightRegion->getDforce()) { regionsChanged = true; for(Segment* s : rightRegion->segments) { leftRegion->segments.append(s); s->region = leftRegion; leftRegion->minTopologicNumber = std::min(leftRegion->minTopologicNumber,s->topologicNumber); } delete rightRegion; regions.removeAll(rightRegion); } } } } // Combining regions } // While regions not changed /* for(Region* r : regions) { qDebug() << "Region:"; for(Segment* s : r->segments) { qDebug() << s->nodes.first()->getName(); } } */ // Order by minTopologicalNumber std::sort(regions.begin(),regions.end(),[](const Region* const r1, const Region* const r2){return r1->minTopologicNumber < r2->minTopologicNumber;}); // Process each region for(Region* r : regions) { newProcessRegion(r,graph); } // Done. Delete regions for(Region* r : regions) { delete r; } }