void TransformerSPRINGEMBEDDER::SpringEmbed(Graph& G, vector<float> dimension_limits, IntermediateStepHandler* intermediatestephandler) { vector<VectorND> tractions; int dimensions = dimension_limits.size(); unstressed_spring_length = dimension_limits[0]; for(int i = 1; i < dimensions; i++) unstressed_spring_length *= dimension_limits[i]; unstressed_spring_length /= G.NumberOfVertices(); unstressed_spring_length = pow(unstressed_spring_length, 1.0f/dimensions) / (dimensions * 2); // init srand ( time(NULL) ); for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++) { Coordinates coordinates; for(int i = 0; i < dimensions; i++) coordinates.push_back(fmod(rand(), dimension_limits[i])); (*a)->SetCoordinates(coordinates); // should make sure that no two vertices have the same position tractions.push_back(VectorND(dimensions)); } float max_movement; iteration = 0; do { // compute movement max_movement = 0; int i = 0; for(VertexIterator a = G.BeginVertices(); a != G.EndVertices(); a++, i++) { VectorND traction = tractions[i] * friction; // compute forces on a by the other vertices VectorND aCoordinates((*a)->GetCoordinates(0)); for(VertexIterator b = G.BeginVertices(); b != G.EndVertices(); b++) { if(b==a) continue; // force on a by vertex b VectorND bCoordinates((*b)->GetCoordinates(0)); traction += coulomb(aCoordinates, bCoordinates); if((*a)->Adjacent(*b)) traction += hooke(aCoordinates, bCoordinates); } tractions[i] = traction; } // execute movement VertexIterator a = G.BeginVertices(); for(int i = 0; a != G.EndVertices(); a++, i++) { Coordinates OldCoordinates = (*a)->GetCoordinates(0); Coordinates NewCoordinates(dimensions); for(int j = 0; j < dimensions; j++) NewCoordinates[j] = max(0.0f,min(dimension_limits[j], OldCoordinates[j] + delta * tractions[i][j] )); (*a)->SetCoordinates( NewCoordinates ); // for the loop-condition float current_movement = 0.0f; for(int j = 0; j < dimensions; j++) current_movement += (OldCoordinates[j] - NewCoordinates[j]) * (OldCoordinates[j] - NewCoordinates[j]); if(sqrt(current_movement) > max_movement) max_movement = sqrt(current_movement); } if(intermediatestephandler != NULL) intermediatestephandler->Handle(&G); if(++iteration > nextincrease) { movement_threshold += 0.01f; nextincrease *= 4; } if(iteration > max_iterations) break; } while(max_movement > movement_threshold*unstressed_spring_length); }
void ExportFilterRGML::Export(Graph& G, ostream& os, VertexColoring& vertexcoloring, EdgeColoring& edgecoloring, float dpi, float edgewidth, float vertexradius) { StringTranslatorXML Translator; os << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; os << "<!-- www.Open-Graphtheory.org -->\n\n"; os << "<rdf:RDF\n" << " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" << " xmlns=\"http://purl.org/puninj/2001/05/rgml-schema#\"\n" << " xmlns:rgml=\"http://purl.org/puninj/2001/05/rgml-schema#\"\n" << ">\n\n"; os << " <Graph rdf:ID=\"graph\" rgml:directed=\"false\">\n"; /// declare vertices os << " <nodes>\n"; os << " <rdf:Bag>\n"; for(VertexIterator v = G.BeginVertices(); v != G.EndVertices(); v++) os << " <rdf:li rdf:resource=\"#n" << (*v)->GetID() << "\"/>\n"; os << " </rdf:Bag>\n"; os << " </nodes>\n\n"; /// declare edges and arcs os << " <edges>\n"; os << " <rdf:Bag>\n"; for(EdgeIterator e = G.BeginEdges(); e != G.EndEdges(); e++) os << " <rdf:li rdf:resource=\"#e" << (*e)->GetID() << "\"/>\n"; os << " </rdf:Bag>\n"; os << " </edges>\n"; os << " </Graph>\n\n"; /// write vertices for(VertexIterator v = G.BeginVertices(); v != G.EndVertices(); v++) os << " <Node rdf:ID=\"n" << (*v)->GetID() << "\" rgml:label=\"" << Translator.Translate((*v)->GetLabel()) << "\"/>\n"; /// write edges for(EdgeIterator ei = G.BeginEdges(); ei != G.EndEdges(); ei++) { Edge* e = *ei; if(e->IsHyperedge()) continue; os << "\n <Edge rdf:ID=\"e" << e->GetID() << "\" directed=\"" << (e->IsEdge()?"false":"true") << "\"" << " rgml:label=\"" << Translator.Translate(e->GetLabel()) << "\">\n"; os << " <source rdf:resource=\"#n" << e->From()->GetID() << "\"/>\n"; os << " <target rdf:resource=\"#n" << e->To()->GetID() << "\"/>\n"; os << " </Edge>\n"; } /// write hyperedges for(EdgeIterator ei = G.BeginEdges(); ei != G.EndEdges(); ei++) { Edge *e = *ei; if(!e->IsHyperedge()) continue; os << "\n <Edge rdf:ID=\"e" << e->GetID() << "\"" << " rgml:label=\"" << Translator.Translate(e->GetLabel()) << "\">\n"; os << " <nodes>\n"; os << " <rdf:Seq>\n"; for(VertexEdgeConnectionIterator conn = e->BeginConnections(); conn != e->EndConnections(); conn++) os << " <rdf:li rdf:resource=\"#n" << (*conn)->GetVertex()->GetID() << "\"/>\n"; os << " </rdf:Seq>\n"; os << " </nodes>\n"; os << " </Edge>\n"; } os << "\n</rdf:RDF>\n"; }