Hello,
first of all this is not my first language so forgive me for any mistakes please.
I just started using sfml so this is probably a newbie question but after several hours of research and still no solution Im totally baffled.
I got a class to manage all my visualisation(draw, display,...) and it looks like this:
SFMLGraphVisualizer #include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <math.h>
#include <sstream>
#include "GraphVisualizer.h"
#define NODERADIUS 30
using namespace std;
class SFMLGraphVisualize : public GraphVisualizer
{
private:
sf::RenderWindow window;
sf::Font font;
public:
SFMLGraphVisualize::SFMLGraphVisualize()
{
//load my font
this->font.loadFromFile("arial.ttf");
}
// ---------------------------------------------------------------------------------------------------------------
void SFMLGraphVisualize::visualize(DiGraph & g)
{
window.create(sf::VideoMode(1024, 768), "myGraph");
Liste<Node*> nodes = g.getNodes();
while (window.isOpen())
{
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window: exit
if (event.type == sf::Event::Closed)
window.close();
}
// Clear screen
window.clear(sf::Color::White);
for (unsigned int i = 0; i < nodes.size(); i++)
{
// Draw nodes
Node* node = nodes.getValueAt(i);
sf::Color color(255, 0, 0);
drawNode(*node, color);
// Draw edges
Liste<Edge*> *edges = g.getEdges(node->getKey());
for (unsigned int j = 0; j < edges->size(); j++)
{
drawEdge(*(edges->getValueAt(j)), sf::Color::Black,
edges->getValueAt(j)->getWeight(), 1);
//this->highlightPath(edges);
}
}
// Update the window
window.display();
}
}
// ---------------------------------------------------------------------------------------------------------------
void SFMLGraphVisualize::drawNode(Node & node, sf::Color nodeColor)
{
sf::CircleShape Circle(NODERADIUS);
Circle.setPosition(node.getPositionX() - NODERADIUS,
node.getPositionY() - NODERADIUS);
Circle.setFillColor(sf::Color::White);
Circle.setOutlineColor(nodeColor);
Circle.setOutlineThickness(5);
window.draw(Circle);
sf::Text Label(node.getKey(), font, 32);
Label.setPosition(node.getPositionX() - NODERADIUS / 2 + 5,
node.getPositionY() - NODERADIUS / 2 - 5);
Label.setFillColor(sf::Color::Blue);
window.draw(Label);
}
// ---------------------------------------------------------------------------------------------------------------
void SFMLGraphVisualize::drawEdge(Edge & edge, sf::Color color, double weight,
int thickness = 1, int arrowMagnitude = 20)
{
sf::Vector2f p(edge.getStartNode()->getPositionX(),
edge.getStartNode()->getPositionY());
sf::Vector2f q(edge.getEndNode()->getPositionX(),
edge.getEndNode()->getPositionY());
// Calculate angle
const double PI = 3.141592653;
double angle = atan2((double)p.y - q.y, (double) p.x - q.x);
// Calculate shortended arrow
q.x = (int) (q.x + NODERADIUS * cos(angle));
q.y = (int) (q.y + NODERADIUS * sin(angle));
p.x = (int) (p.x - NODERADIUS * cos(angle));
p.y = (int) (p.y - NODERADIUS * sin(angle));
sf::Vertex line[2] =
{
sf::Vertex(sf::Vector2f(p.x, p.y), color),
sf::Vertex(sf::Vector2f(q.x, q.y), color)
};
window.draw(line, 2, sf::Lines);
std::stringstream weightstring;
weightstring << weight;
sf::Text Labelweight(weightstring.str(), font, 32);
int size = sqrt(pow(p.x - q.x, 2) + pow(p.y - q.y, 2));
Labelweight.setPosition(p.x - (size / 2) * cos(angle) + 10 * sin(angle),
p.y - (size / 2) * sin(angle) + 10 * cos(angle));
Labelweight.setFillColor(sf::Color::Blue);
window.draw(Labelweight);
// First segment
p.x = (int)(q.x + arrowMagnitude * cos(angle + PI / 8));
p.y = (int)(q.y + arrowMagnitude * sin(angle + PI / 8));
sf::Vertex first[2] =
{
sf::Vertex(sf::Vector2f(p.x, p.y), color),
sf::Vertex(sf::Vector2f(q.x, q.y), color)
};
window.draw(first, 2, sf::Lines);
// Second segment
p.x = (int)(q.x + arrowMagnitude * cos(angle - PI / 8));
p.y = (int)(q.y + arrowMagnitude * sin(angle - PI / 8));
sf::Vertex second[2] =
{
sf::Vertex(sf::Vector2f(p.x, p.y), color),
sf::Vertex(sf::Vector2f(q.x, q.y), color)
};
window.draw(second, 2, sf::Lines);
}
// ---------------------------------------------------------------------------------------------------------------
void SFMLGraphVisualize::highlightPath(Liste<Edge*> *p)
{
for (int it = 0; it < p->size(); it++)
{
drawEdge(*(p->getValueAt(it)), sf::Color::Red, p->getValueAt(it)->getWeight(), 1);
}
}
};
My main looks like this:
main#include <iostream>
#include <SFML/Graphics.hpp>
#include "liste.h"
#include "DiGraph.h"
#include "SFMLGraphVisualize.h"
void createDummyGraph(DiGraph &g)
{
g.addNode(new Node ("Aachen", 100, 600));
g.addNode(new Node("Berlin", 300, 650));
g.addNode(new Node("Koeln", 300, 300));
g.addNode(new Node("Essen", 900, 300));
g.addNode(new Node("Bonn", 300, 150));
g.addNode(new Node("Krefeld", 100, 160));
g.addEdge("Aachen", "Berlin", 7);
g.addEdge("Koeln", "Aachen", 9);
g.addEdge("Aachen", "Krefeld", 7);
g.addEdge("Berlin", "Essen", 40);
g.addEdge("Berlin", "Koeln", 3);
g.addEdge("Koeln", "Essen", 31);
g.addEdge("Bonn", "Essen", 8);
g.addEdge("Krefeld", "Bonn", 1);
}
void driver_1()
{
DiGraph myGraph;
SFMLGraphVisualize graphviz;
createDummyGraph(myGraph);
Liste<Edge *> *path = myGraph.dijkstra("Berlin", "Essen"); // get edges of shortest path
//myGraph.toScreen();
graphviz.highlightPath(path); // highlight shortest path (color red)
graphviz.visualize(myGraph); // show graph
}
int main()
{
driver_1();
}
I can visualize my graph but I cannot highlight the shortest path because I don't know how to do it.
Graph looks like this:
Which order do I need: - draw graph first, highlight afterwards?
- highlight first, draw graph afterwards?
Or something complete different?
I'm really lost right now.
EDITBrain started working again. Found a solution/work around.
Can be closed/removed.