void VisibilityLayout::layout(GraphAttributes &GA, const UpwardPlanRep &UPROrig) { UpwardPlanRep UPR = UPROrig; //clear some data for(edge e : GA.constGraph().edges) { GA.bends(e).clear(); } int minGridDist = 1; for(node v : GA.constGraph().nodes) { if (minGridDist < max(GA.height(v), GA.width(v))) minGridDist = (int) max(GA.height(v), GA.width(v)); } minGridDist = max(minGridDist*2+1, m_grid_dist); CombinatorialEmbedding &gamma = UPR.getEmbedding(); //add edge (s,t) adjEntry adjSrc = nullptr; for(adjEntry adj : UPR.getSuperSource()->adjEntries) { if (gamma.rightFace(adj) == gamma.externalFace()) adjSrc = adj; break; } OGDF_ASSERT(adjSrc != nullptr); edge e_st = UPR.newEdge(adjSrc, UPR.getSuperSink()); // on the right gamma.computeFaces(); gamma.setExternalFace(gamma.rightFace(e_st->adjSource())); constructVisibilityRepresentation(UPR); // the preliminary postion NodeArray<int> xPos(UPR); NodeArray<int> yPos(UPR); // node Position for(node v : UPR.nodes) { NodeSegment vVis = nodeToVis[v]; int x = (int) (vVis.x_l + vVis.x_r)/2 ; // median positioning xPos[v] = x; yPos[v] = vVis.y; if (UPR.original(v) != nullptr) { node vOrig = UPR.original(v); //final position GA.x(vOrig) = x * minGridDist; GA.y(vOrig) = vVis.y * minGridDist; } } //compute bendpoints for(edge e : GA.constGraph().edges) { const List<edge> &chain = UPR.chain(e); for(edge eUPR : chain) { EdgeSegment eVis = edgeToVis[eUPR]; if (chain.size() == 1) { if ((yPos[eUPR->target()] - yPos[eUPR->source()]) > 1) { DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist); DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist); GA.bends(e).pushBack(p1); if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1) GA.bends(e).pushBack(p2); } } else { //short edge if ((yPos[eUPR->target()] - yPos[eUPR->source()]) == 1) { if (UPR.original(eUPR->target()) == nullptr) { node tgtUPR = eUPR->target(); DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist); GA.bends(e).pushBack(p); } } //long edge else { DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist); DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist); GA.bends(e).pushBack(p1); if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1) GA.bends(e).pushBack(p2); if (UPR.original(eUPR->target()) == nullptr) { node tgtUPR = eUPR->target(); DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist); GA.bends(e).pushBack(p); } } } } DPolyline &poly = GA.bends(e); DPoint pSrc(GA.x(e->source()), GA.y(e->source())); DPoint pTgt(GA.x(e->target()), GA.y(e->target())); poly.normalize(pSrc, pTgt); } }
void DominanceLayout::layout(GraphAttributes &GA, const UpwardPlanRep &UPROrig) { UpwardPlanRep UPR = UPROrig; //clear some data for(edge e : GA.constGraph().edges) { GA.bends(e).clear(); } //compute and splite transitiv edges List<edge> splitMe; findTransitiveEdges(UPR, splitMe); for(edge eSplit : splitMe) { UPR.getEmbedding().split(eSplit); } // set up first-/lastout, first-/lastin firstout.init(UPR, nullptr); lastout.init(UPR, nullptr); firstin.init(UPR, nullptr); lastin.init(UPR, nullptr); node s = UPR.getSuperSource(); node t = UPR.getSuperSink(); firstout[t] = lastout[t] = nullptr; firstin[s] = lastin[s] = nullptr; firstin[t] = lastin[t] =t->firstAdj()->theEdge(); adjEntry adjRun = s->firstAdj(); while (UPR.getEmbedding().rightFace(adjRun) != UPR.getEmbedding().externalFace()) { adjRun = adjRun->cyclicSucc(); } lastout[s] = adjRun->theEdge(); firstout[s] = adjRun->cyclicSucc()->theEdge(); for(node v : UPR.nodes) { if (v == t || v == s) continue; adjEntry adj = UPR.leftInEdge(v); firstin[v] = adj->theEdge(); firstout[v] = adj->cyclicSucc()->theEdge(); adjEntry adjRightIn = adj; while (adjRightIn->cyclicPred()->theEdge()->source() != v) adjRightIn = adjRightIn->cyclicPred(); lastin[v] = adjRightIn->theEdge(); lastout[v] = adjRightIn->cyclicPred()->theEdge(); } //compute m_L and m_R for min. area drawing m_L = 0; m_R = 0; for(edge e : UPR.edges) { node src = e->source(); node tgt = e->target(); if (lastin[tgt] == e && firstout[src] == e) m_L++; if (firstin[tgt] == e && lastout[src] == e) m_R++; } // compute preleminary coordinate xPreCoord.init(UPR); yPreCoord.init(UPR); int count = 0; labelX(UPR, s, count); count = 0; labelY(UPR, s, count); // compaction compact(UPR, GA); // map coordinate to GA for(node v : GA.constGraph().nodes) { node vUPR = UPR.copy(v); GA.x(v) = xCoord[vUPR]; GA.y(v) = yCoord[vUPR]; } // add bends to original edges for(edge e : GA.constGraph().edges) { const List<edge> &chain = UPR.chain(e); for(edge eChain : chain) { node tgtUPR = eChain->target(); if (tgtUPR != chain.back()->target()) { DPoint p(xCoord[tgtUPR], yCoord[tgtUPR]); GA.bends(e).pushBack(p); } } } //rotate the drawing for(node v : GA.constGraph().nodes) { double r = sqrt(GA.x(v)*GA.x(v) + GA.y(v)*GA.y(v)); if (r == 0) continue; double alpha = asin(GA.y(v)/r); double yNew = sin(alpha + m_angle)*r; double xNew = cos(alpha + m_angle)*r; GA.x(v) = xNew; GA.y(v) = yNew; } for(edge e : GA.constGraph().edges) { DPolyline &poly = GA.bends(e); DPoint pSrc(GA.x(e->source()), GA.y(e->source())); DPoint pTgt(GA.x(e->target()), GA.y(e->target())); poly.normalize(pSrc, pTgt); for(DPoint &p : poly) { double r = p.distance(DPoint(0,0)); if (r == 0) continue; double alpha = asin( p.m_y/r); double yNew = sin(alpha + m_angle)*r; double xNew = cos(alpha + m_angle)*r; p.m_x = xNew; p.m_y = yNew; } } }