コード例 #1
0
ファイル: scriptie.cpp プロジェクト: bartvdput/scriptie
/*
 * calculate edge orthogonality criterium
 */
double EdgeOrthogonalityCriterium(Graph& G, GraphAttributes& GA) {
	double sum = 0;

	for (edge e : G.edges) {
		node s = e->source();
		node t = e->target();

		double s_x = GA.x(s);
		double s_y = GA.y(s);

		double t_x = GA.x(t);
		double t_y = GA.y(t);

		double angle = abs(atan2(s_y - t_y, t_x - s_x) * 180 / PI);
		Array<double> values = { angle, abs(90.0 - angle), abs(180.0 - angle) };
		double *deviation = min_element(begin(values), end(values));
		*deviation = *deviation / 45;

		sum += *deviation;
	}
	
	double Neo = 1.0 - ((1.0 / G.edges.size()) * sum);

	return Neo;
}
コード例 #2
0
ファイル: PivotMDS.cpp プロジェクト: marvin2k/ogdf
void PivotMDS::pivotMDSLayout(GraphAttributes& GA)
{
	const Graph& G = GA.constGraph();
	bool use3D = GA.has(GraphAttributes::threeD) && DIMENSION_COUNT > 2;

	const int n = G.numberOfNodes();

	// trivial cases
	if (n == 0)
		return;

	if (n == 1) {
		node v1 = G.firstNode();
		GA.x(v1) = 0.0;
		GA.y(v1) = 0.0;
		if (use3D)
			GA.z(v1) = 0.0;
		return;
	}

	// check whether the graph is a path or not
	const node head = getRootedPath(G);
	if (head != nullptr) {
		doPathLayout(GA, head);
	}
	else {
		Array<Array<double> > pivDistMatrix;
		// compute the pivot matrix
		getPivotDistanceMatrix(GA, pivDistMatrix);
		// center the pivot matrix
		centerPivotmatrix(pivDistMatrix);
		// init the coordinate matrix
		Array<Array<double> > coord(DIMENSION_COUNT);
		for (int i = 0; i < coord.size(); i++) {
			coord[i].init(n);
		}
		// init the eigen values array
		Array<double> eVals(DIMENSION_COUNT);
		singularValueDecomposition(pivDistMatrix, coord, eVals);
		// compute the correct aspect ratio
		for (int i = 0; i < coord.size(); i++) {
			eVals[i] = sqrt(eVals[i]);
			for (int j = 0; j < n; j++) {
				coord[i][j] *= eVals[i];
			}
		}
		// set the new positions to the graph
		int i = 0;
		for (node v : G.nodes)
		{
			GA.x(v) = coord[0][i];
			GA.y(v) = coord[1][i];
			if (use3D){
				GA.z(v) = coord[2][i];//cout << coord[2][i] << "\n";
			}
			++i;
		}
	}
}
コード例 #3
0
ファイル: DavidsonHarel.cpp プロジェクト: ogdf/ogdf
//chooses the initial radius of the disk as half the maximum of width and height of
//the initial layout or depending on the value of m_fineTune
void DavidsonHarel::computeFirstRadius(const GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();
	node vFirst = G.firstNode();
	double minX = AG.x(vFirst);
	double minY = AG.y(vFirst);
	double maxX = minX;
	double maxY = minY;
	for(node v : G.nodes) {
		Math::updateMin(minX, AG.x(v));
		Math::updateMax(maxX, AG.x(v));
		Math::updateMin(minY, AG.y(v));
		Math::updateMax(maxY, AG.y(v));
	}
	// compute bounding box of current layout
	// make values nonzero
	double w = maxX-minX+1.0;
	double h = maxY-minY+1.0;

	double ratio = h/w;

	double W = sqrt(G.numberOfNodes() / ratio);

	m_diskRadius = W / 5.0;//allow to move by a significant part of current layout size
	Math::updateMax(m_diskRadius, max(maxX-minX, maxY-minY) / 5.0);

	//TODO: also use node sizes
#if 0
	double lengthSum(0.0);
	for(node v : m_G.nodes) {
		const DRectIntersection &i = shape(v);
		lengthSum += i.width();
		lengthSum += i.width();
		}
		lengthSum /= (2*m_G.numberOfNodes());
		// lengthSum is now the average of all lengths and widths
#endif

	//change the initial radius depending on the settings
	//this is legacy crap
#if 0
	double divo = 2.0;
	if (m_fineTune == tpCoarse) {
		m_diskRadius = 1000.0;
		divo = 0.5;
	}
	if (m_fineTune == tpFine) {
		m_diskRadius = 10.0;
		divo = 15.0;
	}
#if 0
	Math::updateMax(m_diskRadius, max(maxX-minX,maxY-minY));
#endif
	m_diskRadius = max(maxX-minX,maxY-minY);
	m_diskRadius /= divo;
#endif
}
コード例 #4
0
void ComponentSplitterLayout::call(GraphAttributes &GA)
{
	// Only do preparations and call if layout is valid
	if (m_secondaryLayout.valid())
	{
		//first we split the graph into its components
		const Graph& G = GA.constGraph();

		NodeArray<int> componentNumber(G);
		m_numberOfComponents = connectedComponents(G, componentNumber);
		if (m_numberOfComponents == 0) {
			return;
		}

		//std::vector< std::vector<node> > componentArray;
		//componentArray.resize(numComponents);
		//Array<GraphAttributes *> components(numComponents);
		//

		// intialize the array of lists of nodes contained in a CC
		nodesInCC.init(m_numberOfComponents);

		node v;
		forall_nodes(v,G)
			nodesInCC[componentNumber[v]].pushBack(v);

		 // Create copies of the connected components and corresponding
		 // GraphAttributes
		 GraphCopy GC;
		 GC.createEmpty(G);

		 EdgeArray<edge> auxCopy(G);

		 for (int i = 0; i < m_numberOfComponents; i++)
		 {
			 GC.initByNodes(nodesInCC[i],auxCopy);
			 GraphAttributes cGA(GC);
			 //copy information into copy GA
			 forall_nodes(v, GC)
			 {
				cGA.width(v) = GA.width(GC.original(v));
				cGA.height(v) = GA.height(GC.original(v));
				cGA.x(v) = GA.x(GC.original(v));
				cGA.y(v) = GA.y(GC.original(v));
			 }
			 m_secondaryLayout.get().call(cGA);

			 //copy layout information back into GA
			 forall_nodes(v, GC)
			 {
				 node w = GC.original(v);
				 if (w != 0)
					 GA.x(w) = cGA.x(v);
				 GA.y(w) = cGA.y(v);
			 }
		 }
コード例 #5
0
ファイル: DavidsonHarel.cpp プロジェクト: mneumann/tulip
	//chooses the initial radius of the disk as half the maximum of width and height of
	//the initial layout or depending on the value of m_fineTune
	void DavidsonHarel::computeFirstRadius(const GraphAttributes &AG)
	{
		const Graph &G = AG.constGraph();
		node v = G.firstNode();
		double minX = AG.x(v);
		double minY = AG.y(v);
		double maxX = minX;
		double maxY = minY;
		forall_nodes(v,G) {
			minX = min(minX,AG.x(v));
			maxX = max(maxX,AG.x(v));
			minY = min(minY,AG.y(v));
			maxY = max(maxY,AG.y(v));
		}
コード例 #6
0
ファイル: DavidsonHarel.cpp プロジェクト: ogdf/ogdf
//the vertices with degree zero are placed below all other vertices on a horizontal
// line centered with repect to the rest of the drawing
void DavidsonHarel::placeIsolatedNodes(GraphAttributes &AG) const {
	double minX = 0.0;
	double minY = 0.0;
	double maxX = 0.0;

	if (!m_nonIsolatedNodes.empty()) {
		//compute a rectangle that includes all non-isolated vertices
		node vFirst = m_nonIsolatedNodes.front();
		minX = AG.x(vFirst);
		minY = AG.y(vFirst);
		maxX = minX;
		double maxY = minY;
		for (node v : m_nonIsolatedNodes) {
			double xVal = AG.x(v);
			double yVal = AG.y(v);
			double halfHeight = AG.height(v) / 2.0;
			double halfWidth = AG.width(v) / 2.0;
			if (xVal - halfWidth < minX) minX = xVal - halfWidth;
			if (xVal + halfWidth > maxX) maxX = xVal + halfWidth;
			if (yVal - halfHeight < minY) minY = yVal - halfHeight;
			if (yVal + halfHeight > maxY) maxY = yVal + halfHeight;
		}
	}

	// compute the width and height of the largest isolated node
	List<node> isolated;
	const Graph &G = AG.constGraph();
	double maxWidth = 0;
	double maxHeight = 0;
	for (node v : G.nodes)
	if (v->degree() == 0) {
		isolated.pushBack(v);
		if (AG.height(v) > maxHeight) maxHeight = AG.height(v);
		if (AG.width(v) > maxWidth) maxWidth = AG.width(v);
	}
	// The nodes are placed on a line in the middle under the non isolated vertices.
	// Each node gets a box sized 2 maxWidth.
	double boxWidth = 2.0*maxWidth;
	double commonYCoord = minY - (1.5*maxHeight);
	double XCenterOfDrawing = minX + ((maxX - minX) / 2.0);
	double startXCoord = XCenterOfDrawing - 0.5*(isolated.size()*boxWidth);
	double xcoord = startXCoord;
	for (node v : isolated) {
		AG.x(v) = xcoord;
		AG.y(v) = commonYCoord;
		xcoord += boxWidth;
	}
}
コード例 #7
0
ファイル: MultilevelGraph.cpp プロジェクト: ogdf/ogdf
void MultilevelGraph::importAttributesSimple(const GraphAttributes &GA)
{
	OGDF_ASSERT(&(GA.constGraph()) == m_G);

	m_avgRadius = 0.0;

	for(node v : m_G->nodes) {
		double w = GA.width(v);
		double h = GA.height(v);
		if(w > 0 || h > 0) {
			m_radius[v] = sqrt(w*w + h*h) / 2.0f;
		} else {
			m_radius[v] = 1.0f;
		}
		m_avgRadius += m_radius[v];
		m_GA->x(v) = GA.x(v);
		m_GA->y(v) = GA.y(v);
		m_GA->width(v) = GA.width(v);
		m_GA->height(v) = GA.height(v);
	}
	m_avgRadius /= m_G->numberOfNodes();

	for(edge e : m_G->edges) {
		m_weight[e] = GA.doubleWeight(e);
	}
}
コード例 #8
0
ファイル: StressMinimization.cpp プロジェクト: marvin2k/ogdf
void StressMinimization::call(GraphAttributes& GA)
{
	const Graph& G = GA.constGraph();
	// if the graph has at most one node nothing to do
	if (G.numberOfNodes() <= 1) {
		// make it exception save
		for(node v : G.nodes)
		{
			GA.x(v) = 0;
			GA.y(v) = 0;
		}
		return;
	}
	if (m_componentLayout && !isConnected(G)) {
		OGDF_THROW(PreconditionViolatedException);
		return;
	}
	NodeArray<NodeArray<double> > shortestPathMatrix(G);
	NodeArray<NodeArray<double> > weightMatrix(G);
	initMatrices(G, shortestPathMatrix, weightMatrix);
	// if the edge costs are defined by the attribute copy it to an array and
	// construct the proper shortest path matrix
	if (m_hasEdgeCostsAttribute) {
		if (!GA.has(GraphAttributes::edgeDoubleWeight)) {
			OGDF_THROW(PreconditionViolatedException);
			return;
		}
		m_avgEdgeCosts = dijkstra_SPAP(GA, shortestPathMatrix);
		// compute shortest path all pairs
	} else {
		m_avgEdgeCosts = m_edgeCosts;
		bfs_SPAP(G, shortestPathMatrix, m_edgeCosts);
	}
	call(GA, shortestPathMatrix, weightMatrix);
}
コード例 #9
0
ファイル: GdfParser.cpp プロジェクト: marvin2k/ogdf
static bool inline readAttribute(
	GraphAttributes &GA, node v,
	const NodeAttribute &attr, const std::string &value)
{
	const long attrs = GA.attributes();
	switch(attr) {
	case na_name:
		// Not really an attribute, handled elsewhere.
		break;
	case na_label:
		if(attrs & GraphAttributes::nodeLabel) {
			GA.label(v) = value;
		}
		break;
	case na_x:
		if(attrs & GraphAttributes::nodeGraphics) {
			std::istringstream is(value);
			is >> GA.x(v);
		}
		break;
	case na_y:
		if(attrs & GraphAttributes::nodeGraphics) {
			std::istringstream is(value);
			is >> GA.y(v);
		}
コード例 #10
0
ファイル: PivotMDS.cpp プロジェクト: marvin2k/ogdf
void PivotMDS::doPathLayout(GraphAttributes& GA, const node& v)
{
	double xPos = 0;
	node prev = v;
	node cur = v;
	// since the given node is the beginning of the path just
	// use bfs and increment the x coordinate by the average
	// edge costs.
	do {
		GA.x(cur) = xPos;
		GA.y(cur) = 0;
		for(adjEntry adj : cur->adjEntries) {
			node w = adj->twinNode();
			if (!(w == prev) || w == cur) {
				prev = cur;
				cur = w;
				if(m_hasEdgeCostsAttribute) {
					xPos+=GA.doubleWeight(adj->theEdge());
				} else {
					xPos += m_edgeCosts;
				}
				break;
			}
			prev = cur;
		}
	} while (prev != cur);
}
コード例 #11
0
ファイル: scriptie.cpp プロジェクト: bartvdput/scriptie
void BendPromotion(Graph& G, GraphAttributes& GA) {
	List<edge> edges;
	G.allEdges(edges);

	while (!edges.empty()) {
		edge e = edges.popFrontRet();
		DPolyline bends_e = GA.bends(e);
		node s = e->source();
		node t = e->target();

		//check if an edge has bendpoints
		if (!bends_e.empty()) {
			while (!bends_e.empty()) {
				DPoint p = bends_e.front();

				//insert new node
				node n = G.newNode();
				GA.x(n) = p.m_x;
				GA.y(n) = p.m_y;

				edge e_ = G.newEdge(s, n);
				GA.arrowType(e_) = ogdf::EdgeArrow::None;
				GA.strokeColor(e_) = Color("#bababa");
				s = n;

				bends_e.popFront();
			}
			edge e_ = G.newEdge(s, t);
			GA.arrowType(e_) = ogdf::EdgeArrow::None;
			GA.strokeColor(e_) = Color("#bababa");

			G.delEdge(e);
		}
	}
}
コード例 #12
0
ファイル: MultilevelGraph.cpp プロジェクト: ogdf/ogdf
// assumes, that the Graphs of MultilevelGraph and GA are the same, not copies!
void MultilevelGraph::exportAttributesSimple(GraphAttributes &GA) const
{
	OGDF_ASSERT(&(GA.constGraph()) == m_G);

	prepareGraphAttributes(GA);

	for(node v : m_G->nodes) {
		GA.x(v) =  m_GA->x(v);
		GA.y(v) =  m_GA->y(v);
		//TODO: Check what this w,h computation does
		double w = GA.width(v);
		double h = GA.height(v);
		if(w > 0 || h > 0) {
			double factor =  m_radius[v] / sqrt(w*w + h*h) * 2.0f;
			w *= factor;
			h *= factor;
		} else {
			w = h = m_radius[v] * sqrt(2.0f);
		}
		GA.width(v) = w;
		GA.height(v) = h;
		GA.weight(v) = m_reverseNodeMergeWeight[v->index()];
	}

	for(edge e : m_G->edges) {
		GA.doubleWeight(e) = m_weight[e];
	}
}
コード例 #13
0
ファイル: GexfParser.cpp プロジェクト: ogdf/ogdf
static inline bool readVizAttribute(
	GraphAttributes &GA,
	node v,
	const pugi::xml_node tag)
{
	const long attrs = GA.attributes();

	if(string(tag.name()) == "viz:position") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute xAttr = tag.attribute("x");
			pugi::xml_attribute yAttr = tag.attribute("y");
			pugi::xml_attribute zAttr = tag.attribute("z");

			if(!xAttr || !yAttr) {
				GraphIO::logger.lout() << "Missing \"x\" or \"y\" in position tag." << std::endl;
				return false;
			}

			GA.x(v) = xAttr.as_int();
			GA.y(v) = yAttr.as_int();

			// z attribute is optional and avaliable only in \a threeD mode
			GA.y(v) = yAttr.as_int();
			if (zAttr && (attrs & GraphAttributes::threeD)) {
				GA.z(v) = zAttr.as_int();
			}
		}
	} else if(string(tag.name()) == "viz:size") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute valueAttr = tag.attribute("value");
			if (!valueAttr) {
				GraphIO::logger.lout() << "\"size\" attribute is missing a value." << std::endl;
				return false;
			}

			double size = valueAttr.as_double();
			GA.width(v) = size * LayoutStandards::defaultNodeWidth();
			GA.height(v) = size * LayoutStandards::defaultNodeHeight();
		}
	} else if(string(tag.name()) == "viz:shape") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute valueAttr = tag.attribute("value");
			if(!valueAttr) {
				GraphIO::logger.lout() << "\"shape\" attribute is missing a value." << std::endl;
				return false;
			}

			GA.shape(v) = toShape(valueAttr.value());
		}
	} else if(string(tag.name()) == "viz:color") {
		if(attrs & GraphAttributes::nodeStyle) {
			return readColor(GA.fillColor(v), tag);
		}
	} else {
		GraphIO::logger.lout() << "Incorrect tag: \"" << tag.name() << "\"." << std::endl;
		return false;
	}

	return true;
}
コード例 #14
0
ファイル: GraphMLParser.cpp プロジェクト: mneumann/tulip
bool GraphMLParser::readData(
	GraphAttributes &GA,
	const node &v, const XmlTagObject &nodeData)
{
	XmlAttributeObject *keyId;
	nodeData.findXmlAttributeObjectByName("key", keyId);

	if(keyId == NULL) {
		cerr << "ERROR: Node data does not have a key.\n";
		return false;
	}

	const long attrs = GA.attributes();
	std::stringstream value(nodeData.getValue());

	switch (graphml::toAttribute(m_attrName[keyId->getValue()])) {
	case graphml::a_nodeLabel:
		if(attrs & GraphAttributes::nodeLabel) {
			value >> GA.label(v);
		}
		break;
	case graphml::a_x:
		if(attrs & GraphAttributes::nodeGraphics) {
			value >> GA.x(v);
		}
コード例 #15
0
ファイル: LayoutStatistics.cpp プロジェクト: marvin2k/ogdf
	double LayoutStatistics::edgeLengths(
		const GraphAttributes &ga,
		double *pMinLength,
		double *pMaxLength,
		double *pAvgLength,
		double *pStdDeviation,
		bool    considerSelfLoops)
	{
		const Graph &G = ga.constGraph();
		int m = G.numberOfEdges();

		double totalLength = 0, minLength = numeric_limits<double>::max(), maxLength = -numeric_limits<double>::max();

		EdgeArray<double> len(G);
		int nSelfLoops = 0;

		for(edge e : G.edges) {
			if(!considerSelfLoops && e->isSelfLoop()) {
				nSelfLoops++;
				continue;
			}

			const DPolyline &dpl = ga.bends(e);

			if(!dpl.empty()) {
				len[e] = dpl.length();

			} else {
				DPoint pv = DPoint(ga.x(e->source()),ga.y(e->source()));
				DPoint pw = DPoint(ga.x(e->target()),ga.y(e->target()));
				len[e] = pv.distance(pw);
			}

			totalLength += len[e];
			minLength = min(minLength, len[e]);
			maxLength = max(maxLength, len[e]);
		}

		m -= nSelfLoops;

		double avgEdgeLength = totalLength / m;
		if(pAvgLength) *pAvgLength = avgEdgeLength;
		if(pMinLength) *pMinLength = minLength;
		if(pMaxLength) *pMaxLength = maxLength;

		if(pStdDeviation) {
			double sum = 0;
			for(edge e : G.edges) {
				if(!considerSelfLoops && e->isSelfLoop())
					continue;
				double d = len[e] - avgEdgeLength;
				sum += d*d;
			}

			*pStdDeviation = sqrt(sum / m);
		}

		return totalLength;
	}
コード例 #16
0
ファイル: FastMultipoleEmbedder.cpp プロジェクト: ogdf/ogdf
void FastMultipoleMultilevelEmbedder::writeCurrentToGraphAttributes(GraphAttributes& GA)
{
	for(node v : m_pCurrentGraph->nodes)
	{
		GA.x(v) = (*m_pCurrentNodeXPos)[v];
		GA.y(v) = (*m_pCurrentNodeYPos)[v];
	}
}
コード例 #17
0
ファイル: DavidsonHarel.cpp プロジェクト: ogdf/ogdf
//this is the main optimization routine with the loop that lowers the temperature
//and the disk radius geometrically until the temperature is zero. For each
//temperature, a certain number of new positions for a random vertex are tried
void DavidsonHarel::call(GraphAttributes &AG)
{
	initParameters();

	m_shrinkingFactor = m_shrinkFactor;

	OGDF_ASSERT(!m_energyFunctions.empty());

	const Graph &G = AG.constGraph();
	//compute the list of vertices with degree greater than zero
	G.allNodes(m_nonIsolatedNodes);
	ListIterator<node> it,itSucc;
	for(it = m_nonIsolatedNodes.begin(); it.valid(); it = itSucc) {
		itSucc = it.succ();
		if((*it)->degree() == 0) m_nonIsolatedNodes.del(it);
	}
	if(G.numberOfEdges() > 0) { //else only isolated nodes
		computeFirstRadius(AG);
		computeInitialEnergy();
		if(m_numberOfIterations == 0)
			m_numberOfIterations = m_nonIsolatedNodes.size() * m_iterationMultiplier;
		//this is the main optimization loop
		while(m_temperature > 0) {
			//iteration loop for each temperature
			for(int ic = 1; ic <= m_numberOfIterations; ic ++) {
				DPoint newPos;
				//choose random vertex and new position for vertex
				node v = computeCandidateLayout(AG,newPos);
				//compute candidate energy and decide if new layout is chosen
				ListIterator<double> it2 = m_weightsOfEnergyFunctions.begin();
				double newEnergy = 0.0;
				for(EnergyFunction *f : m_energyFunctions) {
					newEnergy += f->computeCandidateEnergy(v,newPos) * (*it2);
					++it2;
				}
				OGDF_ASSERT(newEnergy >= 0.0);
				//this tests if the new layout is accepted. If this is the case,
				//all energy functions are informed that the new layout is accepted
				if(testEnergyValue(newEnergy)) {
					for(EnergyFunction *f : m_energyFunctions)
						f->candidateTaken();
					AG.x(v) = newPos.m_x;
					AG.y(v) = newPos.m_y;
					m_energy = newEnergy;
				}
			}
			//lower the temperature and decrease the disk radius
			m_temperature = (int)floor(m_temperature*m_coolingFactor);
			m_diskRadius *= m_shrinkingFactor;
		}
	}
	//if there are zero degree vertices, they are placed using placeIsolatedNodes
	if(m_nonIsolatedNodes.size() != G.numberOfNodes())
		placeIsolatedNodes(AG);
}
コード例 #18
0
ファイル: GraphIO_svg.cpp プロジェクト: mneumann/tulip
static void compute_bounding_box(const GraphAttributes &A, double &xmin, double &ymin, double &xmax, double &ymax)
{
	const Graph &G = A.constGraph();
	if(G.numberOfNodes() == 0) {
		xmin = xmax = ymin = ymax = 0;
		return;
	}

	node v = G.firstNode();
	xmin = xmax = A.x(v),
	ymin = ymax = A.y(v);

	forall_nodes(v, G) {
		double lw = (A.attributes() & GraphAttributes::nodeStyle) ? 0.5*A.strokeWidth(v) : 0.5;

		xmax = max(xmax, A.x(v) + A.width (v)/2 + lw);
		ymax = max(ymax, A.y(v) + A.height(v)/2 + lw);
		xmin = min(xmin, A.x(v) - A.width (v)/2 - lw);
		ymin = min(ymin, A.y(v) - A.height(v)/2 - lw);
	}
コード例 #19
0
ファイル: BertaultLayout.cpp プロジェクト: YueLinHo/ogdf
void BertaultLayout::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();
	if(G.numberOfNodes() == 0)
		return;
	if( (AG.attributes() & GraphAttributes::nodeGraphics) == 0 )
		return;
	if( (AG.attributes() & GraphAttributes::edgeGraphics) != 0 )
		AG.clearAllBends();
	if(iter_no==0)
		iter_no=G.numberOfNodes()*10;
	if(req_length==0)
	{
		edge e;
		forall_edges(e,G)
		{
			node a=e->source();
			node b=e->target();
			req_length+=sqrt((AG.x(a)-AG.x(b))*(AG.x(a)-AG.x(b))+(AG.y(a)-AG.y(b))*(AG.y(a)-AG.y(b)));
		}
コード例 #20
0
ファイル: FMMMLayout.cpp プロジェクト: SiteView/NNMQT
inline void FMMMLayout :: import_NodeAttributes(const Graph& G, GraphAttributes& GA,
						NodeArray<NodeAttributes>& A)
{
 node v;
 DPoint position;

 forall_nodes(v,G)
   {
     position.m_x = GA.x(v);
     position.m_y = GA.y(v);
     A[v].set_NodeAttributes(GA.width(v),GA.height(v),position,NULL,NULL); 
   }
コード例 #21
0
ファイル: StressMinimization.cpp プロジェクト: marvin2k/ogdf
void StressMinimization::copyLayout(
	const GraphAttributes& GA,
	NodeArray<double>& newX,
	NodeArray<double>& newY)
{
	// copy the layout
	for(node v : GA.constGraph().nodes)
	{
		newX[v] = GA.x(v);
		newY[v] = GA.y(v);
	}
}
コード例 #22
0
ファイル: GraphIO_dot.cpp プロジェクト: ogdf/ogdf
static inline void writeAttributes(
	std::ostream &out,
	const GraphAttributes &GA, const node &v)
{
	const long flags = GA.attributes();

	out << "[";

	bool separator = false; // Wheter to put separator before attribute.

	if(flags & GraphAttributes::nodeId) {
		writeAttribute(out, separator, "id", GA.idNode(v));
	}

	if(flags & GraphAttributes::nodeLabel) {
		writeAttribute(out, separator, "label", GA.label(v));
	}

	if(flags & GraphAttributes::nodeTemplate) {
		writeAttribute(out, separator, "comment", GA.templateNode(v));
	}

	if(flags & GraphAttributes::nodeGraphics) {
		writeAttribute(out, separator, "width", GA.width(v));
		writeAttribute(out, separator, "height", GA.height(v));
		writeAttribute(out, separator, "shape", dot::toString(GA.shape(v)));

		out << ", pos=\"" << GA.x(v) << "," << GA.y(v);
		if(flags & GraphAttributes::threeD) {
			out << "," << GA.z(v);
		}
		out << "\"";
	}

	if(flags & GraphAttributes::nodeStyle) {
		writeAttribute(out, separator, "color", GA.strokeColor(v));
		writeAttribute(out, separator, "fillcolor", GA.fillColor(v));
		writeAttribute(out, separator, "stroketype", toString(GA.strokeType(v)));
		writeAttribute(out, separator, "strokewidth", GA.strokeWidth(v));
		writeAttribute(out, separator, "fillpattern", toString(GA.fillPattern(v)));
	}

	if(flags & GraphAttributes::nodeType) {
		writeAttribute(out, separator, "type", int(GA.type(v)));
	}

	if(flags & GraphAttributes::nodeWeight) {
		writeAttribute(out, separator, "weight", GA.weight(v));
	}

	out << "]";
}
コード例 #23
0
ファイル: scriptie.cpp プロジェクト: bartvdput/scriptie
// create testGraph to test criteria imlementations
void CreateGraph(Graph& G, GraphAttributes& GA) {
	// add nodes
	node zero = G.newNode();
	node one = G.newNode();
	node two = G.newNode();
	node three = G.newNode();
	node four = G.newNode();

	// set node positions
	GA.x(zero) = 4 * NODE_WIDTH;
	GA.y(zero) = 0;

	GA.x(one) = 4 * NODE_WIDTH;
	GA.y(one) = 4 * NODE_HEIGHT;

	GA.x(two) = 0;
	GA.y(two) = 2 * NODE_HEIGHT;

	GA.x(three) = 4 * NODE_WIDTH;
	GA.y(three) = 8 * NODE_HEIGHT;

	GA.x(four) = 0;
	GA.y(four) = 8 * NODE_HEIGHT;

	// add edges
	edge zero_one = G.newEdge(zero, one);
	edge zero_three = G.newEdge(zero, three);
	edge zero_four = G.newEdge(zero, four);
	edge one_two = G.newEdge(one, two);
	edge one_three = G.newEdge(one, three);
	edge two_three = G.newEdge(two, three);

	DPolyline &p = GA.bends(zero_three);
	p.pushBack(DPoint(6 * NODE_WIDTH, 2 * NODE_HEIGHT));
	p.pushBack(DPoint(6 * NODE_WIDTH, 6 * NODE_HEIGHT));
}
コード例 #24
0
ファイル: StressMinimization.cpp プロジェクト: marvin2k/ogdf
double StressMinimization::calcStress(
	const GraphAttributes& GA,
	NodeArray<NodeArray<double> >& shortestPathMatrix,
	NodeArray<NodeArray<double> >& weightMatrix)
{
	double stress = 0;
	for (node v = GA.constGraph().firstNode(); v != nullptr; v = v->succ()) {
		for (node w = v->succ(); w != nullptr; w = w->succ()) {
			double xDiff = GA.x(v) - GA.x(w);
			double yDiff = GA.y(v) - GA.y(w);
			double zDiff = 0.0;
			if (GA.has(GraphAttributes::threeD))
			{
				zDiff = GA.z(v) - GA.z(w);
			}
			double dist = sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
			if (dist != 0) {
				stress += weightMatrix[v][w] * (shortestPathMatrix[v][w] - dist)
					* (shortestPathMatrix[v][w] - dist);//
			}
		}
	}
	return stress;
}
コード例 #25
0
ファイル: GridLayoutModule.cpp プロジェクト: ogdf/ogdf
void GridLayoutModule::mapGridLayout(const Graph &G,
	GridLayout &gridLayout,
	GraphAttributes &AG)
{
	// maximum width of columns and rows
	double maxWidth = 0;
	double yMax = 0;

	for(node v : G.nodes) {
		Math::updateMax<double>(maxWidth, AG.width(v));
		Math::updateMax<double>(maxWidth, AG.height(v));
		Math::updateMax<double>(yMax, gridLayout.y(v));
	}

	maxWidth += m_separation;

	// set position of nodes
	for(node v : G.nodes) {
		AG.x(v) = gridLayout.x(v) * maxWidth;
		AG.y(v) = (yMax - gridLayout.y(v)) * maxWidth;
	}

	// transform bend points of edges
	for(edge e : G.edges) {
		IPolyline ipl = gridLayout.polyline(e);

		// Remove superfluous bendpoints
		node v = e->source();
		while(!ipl.empty() && ipl.front() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
			ipl.popFront();
		}
		v = e->target();
		while(!ipl.empty() && ipl.back() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
			ipl.popBack();
		}

		DPolyline &dpl = AG.bends(e);
		dpl.clear();

		for (const IPoint &ip : ipl) {
			dpl.pushBack(DPoint(ip.m_x*maxWidth, (yMax-ip.m_y)*maxWidth));
		}

		dpl.normalize();
	}
}
コード例 #26
0
ファイル: RadialTreeLayout.cpp プロジェクト: lncosie/ogdf
void RadialTreeLayout::ComputeCoordinates(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();

	//double mx = m_outerRadius + 0.5*m_connectedComponentDistance;
	//double my = mx;

	for(node v : G.nodes) {
		double r = m_radius[m_level[v]];
		double alpha = m_angle[v];

		AG.x(v) = r * cos(alpha);
		AG.y(v) = r * sin(alpha);
	}

	AG.clearAllBends();
}
コード例 #27
0
ファイル: DavidsonHarel.cpp プロジェクト: mneumann/tulip
	//chooses random vertex and a new random position for it on a circle with radius m_diskRadius
	//around its previous position
	node DavidsonHarel::computeCandidateLayout(
	const GraphAttributes &AG,
	DPoint &newPos) const
	{
		int randomPos = randomNumber(0,m_nonIsolatedNodes.size()-1);
		node v = *(m_nonIsolatedNodes.get(randomPos));
		double oldx = AG.x(v);
		double oldy = AG.y(v);
		double randomAngle = randNum() * 2.0 * Math::pi;
		newPos.m_y = oldy+sin(randomAngle)*m_diskRadius;
		newPos.m_x = oldx+cos(randomAngle)*m_diskRadius;
#ifdef OGDF_DEBUG
		double dist = sqrt((newPos.m_x - oldx)*(newPos.m_x - oldx)+(newPos.m_y-oldy)*(newPos.m_y-oldy));
		OGDF_ASSERT(dist > 0.99 * m_diskRadius && dist < 1.01 * m_diskRadius);
#endif
		return v;
	}
コード例 #28
0
ファイル: scriptie.cpp プロジェクト: bartvdput/scriptie
/*
 * calculate node orthogonality criterium
 *
 * TODO: calculate value '2 * NODE_SIZE' from: 
 * GCD of the set of vertical and horizontal (pixel) differences between all geometrically adjacent nodes.
 */
double NodeOrthogonalityCriterium(Graph& G, GraphAttributes& GA) {
	double width = 0, height = 0;
	for (node n : G.nodes) {
		double nodeWidth = GA.x(n) / (2 * NODE_WIDTH);
		double nodeHeight = GA.y(n) / (2 * NODE_HEIGHT);

		if (nodeWidth > width)
			width = nodeWidth;

		if (nodeHeight > height)
			height = nodeHeight;
	}

	double A = (1 + width)*(1 + height);
	double Nno = G.nodes.size() / A;

	return Nno;
}
コード例 #29
0
ファイル: TutteLayout.cpp プロジェクト: lncosie/ogdf
void TutteLayout::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();

	List<node> fixedNodes;
	List<DPoint> positions;

	double diam =
	sqrt((m_bbox.width()) * (m_bbox.width())
		 + (m_bbox.height()) * (m_bbox.height()));

	// handle graphs with less than two nodes
	switch (G.numberOfNodes()) {
		case 0:
			return;
		case 1:
			node v = G.firstNode();

			DPoint center(0.5 * m_bbox.width(),0.5 * m_bbox.height());
			center = center + m_bbox.p1();

			AG.x(v) = center.m_x;
			AG.y(v) = center.m_y;

			return;
	}

	// increase radius to have no overlap on the outer circle
	node v = G.firstNode();

	double r        = diam/2.8284271;
	int n           = G.numberOfNodes();
	double nodeDiam = 2.0*sqrt((AG.width(v)) * (AG.width(v))
			 + (AG.height(v)) * (AG.height(v)));

	if(r<nodeDiam/(2*sin(2*Math::pi/n))) {
		r=nodeDiam/(2*sin(2*Math::pi/n));
		m_bbox = DRect (0.0, 0.0, 2*r, 2*r);
	}

	setFixedNodes(G,fixedNodes,positions,r);

	doCall(AG,fixedNodes,positions);
}
コード例 #30
0
ファイル: GraphIO_dot.cpp プロジェクト: marvin2k/ogdf
static inline void writeAttributes(
	std::ostream &out,
	const GraphAttributes &GA, const node &v)
{
	const long flags = GA.attributes();

	out << "[";

	bool separator = false; // Wheter to put separator before attribute.

	if(flags & GraphAttributes::nodeId) {
		writeAttribute(out, separator, "id", GA.idNode(v));
	}

	if(flags & GraphAttributes::nodeLabel) {
		writeAttribute(out, separator, "label", GA.label(v));
	}

	if(flags & GraphAttributes::nodeTemplate) {
		writeAttribute(out, separator, "comment", GA.templateNode(v));
	}

	if(flags & GraphAttributes::nodeGraphics) {
		writeAttribute(out, separator, "width", GA.width(v));
		writeAttribute(out, separator, "height", GA.height(v));
		writeAttribute(out, separator, "shape", dot::toString(GA.shape(v)));

		out << ", pos=\"" << GA.x(v) << "," << GA.y(v);
		if(flags & GraphAttributes::threeD) {
			out << "," << GA.z(v);
		}
		out << "\"";
	}

	if(flags & GraphAttributes::nodeStyle) {
		writeAttribute(out, separator, "color", GA.strokeColor(v));
		writeAttribute(out, separator, "fillcolor", GA.fillColor(v));
	}

	// NOTE: Node type is weird and (probably) cannot be mapped to DOT.
	// NOTE: Node weight is not supported.

	out << "]";
}