Ejemplo n.º 1
0
void DominanceLayout::findTransitiveEdges(const UpwardPlanRep &UPR, List<edge> &edges)
{
	// for st-graphs:
	// e = (u,v) transitive <=> ex. face f: e in f and u source-switch and v = sink-switch
	for(face f : UPR.getEmbedding().faces) {
		if (f == UPR.getEmbedding().externalFace())
			continue;

		for(adjEntry adj : f->entries)
		{
			node src = adj->theEdge()->source();
			node tgt = adj->theEdge()->target();
			if ( (adj->faceCycleSucc()->theEdge()->source() == src && adj->faceCyclePred()->theEdge()->target() == tgt)
				|| (adj->faceCycleSucc()->theEdge()->target() == tgt && adj->faceCyclePred()->theEdge()->source() == src))
			{
					edges.pushBack(adj->theEdge());
					break;
			}
		}
	}
}
Ejemplo n.º 2
0
void SubgraphUpwardPlanarizer::merge(
	const GraphCopy &GC,
	UpwardPlanRep &UPR_res,
	const GraphCopy &block,
	UpwardPlanRep &UPR)
{
	node startUPR = UPR.getSuperSource()->firstAdj()->theEdge()->target();
	node startRes;

	node startG = GC.original(block.original(UPR.original(startUPR)));

	bool empty = UPR_res.empty();

	if (empty) {

		OGDF_ASSERT(startG == 0);

		// contruct a node in UPR_res assocciated with startUPR
		startRes = UPR_res.newNode();
		UPR_res.m_isSinkArc.init(UPR_res, false);
		UPR_res.m_isSourceArc.init(UPR_res, false);
		UPR_res.s_hat = startRes;
	}
	else {
		startRes = UPR_res.copy(startG);
	}

	OGDF_ASSERT(startRes != 0);

	// compute the adjEntry position (in UPR_res) of the cutvertex startRes
	adjEntry pos = nullptr;
	if (!empty) {
		adjEntry adj_ext = nullptr, adj_int = nullptr;
		for(adjEntry run : startRes->adjEntries) {
			if (UPR_res.getEmbedding().rightFace(run) == UPR_res.getEmbedding().externalFace()) {
				adj_ext = run;
				break;
			}
			if (run->theEdge()->source() == startRes)
				adj_int = run;
		}
		// cutvertex is a sink in UPR_res
		if (adj_ext == nullptr && adj_int == nullptr) {
			pos = UPR_res.sinkSwitchOf(startRes);
		}
		else {
			if (adj_ext == nullptr)
				pos = adj_int;
			else
				pos = adj_ext;
		}
		OGDF_ASSERT(pos != 0);
	}

	// construct for each node (except the two super sink and the super source) of UPR a associated of UPR to UPR_res
	NodeArray<node> nodeUPR2UPR_res(UPR, nullptr);
	nodeUPR2UPR_res[startUPR] = startRes;
	for(node v : UPR.nodes) {

		// allready constructed or is super sink or super source
		if (v == startUPR || v == UPR.getSuperSink() || v == UPR.getSuperSink()->firstAdj()->theEdge()->source() || v == UPR.getSuperSource())
			continue;

		node vNew;
		if (UPR.original(v) != nullptr ) {
			node vG = GC.original(block.original((UPR.original(v))));
			if (vG != nullptr)
				vNew = UPR_res.newNode(vG);
			else
				vNew = UPR_res.newNode(); //vG is the super source
		}
		else // crossing dummy, no original node
			vNew = UPR_res.newNode();
		nodeUPR2UPR_res[v] = vNew;
	}

	//add edges of UPR to UPR_res
	EdgeArray<edge> edgeUPR2UPR_res(UPR, nullptr);
	for(edge e : block.edges) {

		if (e->source()->indeg()==0) // the artificial edge with the super source
			continue;

		List<edge> chains = UPR.chain(e);
		edge eG = nullptr, eGC = block.original(e);
		eG = GC.original(eGC);

		OGDF_ASSERT(!chains.empty());

		//construct new edges in UPR_res
		for(edge eChain : chains) {
			node tgt = nodeUPR2UPR_res[eChain->target()];
			node src = nodeUPR2UPR_res[eChain->source()];
			edge eNew = UPR_res.newEdge(src, tgt);
			edgeUPR2UPR_res[eChain] = eNew;

			if (UPR.isSinkArc(UPR.copy(e)))
				UPR_res.m_isSinkArc[eNew] = true;
			if (UPR.isSourceArc(UPR.copy(e)))
				UPR_res.m_isSourceArc[eNew] = true;

			if (eG == nullptr) { // edge is associated with a sink arc
				UPR_res.m_eOrig[eNew] = nullptr;
				continue;
			}

			UPR_res.m_eOrig[eNew] = eG;
			if (chains.size() == 1) { // e is not split
				UPR_res.m_eCopy[eG].pushBack(eNew);
				UPR_res.m_eIterator[eNew] = UPR_res.m_eCopy[eG].begin();
				break;
			}
			UPR_res.m_eCopy[eG].pushBack(eNew);
			UPR_res.m_eIterator[eNew] = UPR_res.m_eCopy[eG].rbegin();
		}
	}


	///*
	//* embed the new component in UPR_res with respect to the embedding of UPR
	//*/

	// for the cut vertex
	if (!empty) {
		adjEntry run = UPR.getAdjEntry(UPR.getEmbedding(), startUPR, UPR.getEmbedding().externalFace());
		run = run->cyclicSucc();
		adjEntry adjStart = run;
		do {
			if (edgeUPR2UPR_res[run->theEdge()] != nullptr) {
				adjEntry adj_UPR_res = edgeUPR2UPR_res[run->theEdge()]->adjSource();
				UPR_res.moveAdjAfter(adj_UPR_res, pos);
				pos = adj_UPR_res;
			}
			run = run->cyclicSucc();
		} while(run != adjStart);
	}

	for(node v : UPR.nodes) {
		if (v == startUPR && !empty)
			continue;

		node v_UPR_res = nodeUPR2UPR_res[v];
		List<adjEntry> adj_UPR, adj_UPR_res;
		v->allAdjEntries(adj_UPR);

		// convert adj_UPR of v to adj_UPR_res of v_UPR_res
		for(adjEntry adj : adj_UPR) {
			edge e_res = edgeUPR2UPR_res[adj->theEdge()];
			if (e_res == nullptr) // associated edges in UPR_res
				continue;
			adjEntry adj_res = e_res->adjSource();
			if (adj_res->theNode() != v_UPR_res)
				adj_res = adj_res->twin();
			adj_UPR_res.pushBack(adj_res);
		}

		UPR_res.sort(v_UPR_res, adj_UPR_res);
	}

	/*
	//---------------------------------------------------debug
	if (!UPR_res.empty()) {
		GraphAttributes GA_UPR_res(UPR_res, GraphAttributes::nodeGraphics|
				GraphAttributes::edgeGraphics|
				GraphAttributes::nodeColor|
				GraphAttributes::edgeColor|
				GraphAttributes::nodeLabel|
				GraphAttributes::edgeLabel
				);
		GA_UPR_res.setAllHeight(30.0);
		GA_UPR_res.setAllWidth(30.0);
		// label the nodes with their index
		for(node z : GA_UPR_res.constGraph().nodes) {
			GA_UPR_res.label(z) = to_string(z->index());
		}
		GA_UPR_res.writeGML("c:/temp/UPR_res_tmp.gml");
		cout << "UPR_res_tmp faces:";
		UPR_res.outputFaces(UPR_res.getEmbedding());
	}

	GraphAttributes GA_UPR(UPR, GraphAttributes::nodeGraphics|
				GraphAttributes::edgeGraphics|
				GraphAttributes::nodeColor|
				GraphAttributes::edgeColor|
				GraphAttributes::nodeLabel|
				GraphAttributes::edgeLabel
				);
	GA_UPR.setAllHeight(30.0);
	GA_UPR.setAllWidth(30.0);
	// label the nodes with their index
	for(node z : GA_UPR.constGraph().nodes) {
		GA_UPR.label(z) = to_string(z->index());
	}
	GA_UPR.writeGML("c:/temp/UPR_tmp.gml");
	cout << "UPR_tmp faces:";
	UPR.outputFaces(UPR.getEmbedding());
	//end -----------------------------------------------debug
	*/

	// update UPR_res
	UPR_res.initMe();
}
Ejemplo n.º 3
0
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);
	}
}
Ejemplo n.º 4
0
void VisibilityLayout::constructDualGraph(UpwardPlanRep &UPR)
{
	CombinatorialEmbedding &gamma = UPR.getEmbedding();

	faceToNode.init(gamma, nullptr);
	leftFace_node.init(UPR, nullptr);
	rightFace_node.init(UPR, nullptr);
	leftFace_edge.init(UPR, nullptr);
	rightFace_edge.init(UPR, nullptr);

	//construct a node for each face f
	for(face f : gamma.faces) {
		faceToNode[f] = D.newNode();

		if (f == gamma.externalFace())
			s_D = faceToNode[f] ;

		//compute face switches
		node s = nullptr, t = nullptr;
		for(adjEntry adj : f->entries) {
			adjEntry adjNext = adj->faceCycleSucc();
			if (adjNext->theEdge()->source() == adj->theEdge()->source())
				s = adjNext->theEdge()->source();
			if (adjNext->theEdge()->target() == adj->theEdge()->target())
				t = adjNext->theEdge()->target();
		}
		OGDF_ASSERT(s);
		OGDF_ASSERT(t);

		//compute left and right face
		bool passSource = false;
		adjEntry adj;
		if (f == gamma.externalFace()) {
			adj = UPR.getSuperSink()->firstAdj();
			if (gamma.rightFace(adj) != gamma.externalFace())
				adj = adj->cyclicSucc();
		}
		else
			adj = UPR.getAdjEntry(gamma, t, f);

		adjEntry adjBegin = adj;
		do {
			node v = adj->theEdge()->source();
			if (!passSource) {
				if (v != s)
					leftFace_node[v] = f;
				leftFace_edge[adj->theEdge()] = f;
			}
			else {
				if (v != s)
					rightFace_node[v] = f;
				rightFace_edge[adj->theEdge()] = f;
			}
			if (adj->theEdge()->source() == s)
				passSource = true;
			adj = adj->faceCycleSucc();
		} while(adj != adjBegin);
	}
	t_D = D.newNode(); // the second (right) node associated with the external face

	//construct dual edges
	for(edge e : UPR.edges) {
		face f_r = rightFace_edge[e];
		face f_l = leftFace_edge[e];
		node u = faceToNode[f_l];
		node v = faceToNode[f_r];
		if (f_r == gamma.externalFace() || f_r == f_l)
			D.newEdge(u, t_D);
		else
			D.newEdge(u,v);
	}

	OGDF_ASSERT(isConnected(D));
}
Ejemplo n.º 5
0
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;
		}

	}
}