Using dijkstra, buggy.

for/release
Denes Matetelki 10 years ago
parent 18afa617b3
commit dfdbe65c5b

1
.gitignore vendored

@ -8,3 +8,4 @@ cmake_install.cmake
# graph
graph.kdev4
libstdcxx-profile.*
*.xml

@ -1,8 +1,6 @@
cmake_minimum_required (VERSION 2.6)
project (PROJECT_QGRAPH)
set ( CMAKE_CXX_COMPILER "/usr/bin/g++-4.9.0")
set (CXX_FLAGS "-Wall -Wextra -pedantic -Wshadow "
"-Wpointer-arith -Wcast-qual "
"-ggdb "
@ -37,4 +35,4 @@ make clean &&
find -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} \\+ &&
rm Makefile &&
rm moc_*
)
)

@ -11,6 +11,7 @@ static double TwoPi = 2.0 * Pi;
Edge::Edge(Node* s, Node* d, Edge::ArrowStyle arrowStyle )
: m_arrowStyle(arrowStyle)
, arrowSize(10)
, m_isRoute(false)
{
setAcceptedMouseButtons(0);
source = s;
@ -73,7 +74,11 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
return;
// Draw the line itself
painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
if (m_isRoute)
painter->setPen(QPen(Qt::red, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
else
painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawLine(line);
// Draw the arrows

@ -21,6 +21,9 @@ public:
Node *sourceNode() const;
Node *destNode() const;
bool isRoute() const { return m_isRoute; }
void setIsRoute(bool is_route = true) { m_isRoute = is_route; update(); }
void adjust();
enum { Type = UserType + 2 };
@ -37,6 +40,7 @@ private:
QPointF sourcePoint;
QPointF destPoint;
qreal arrowSize;
bool m_isRoute;
};
#endif

@ -4,6 +4,7 @@
#include "node.hpp"
#include <graph/graph.hpp>
#include <graph/graph_algorithms.hpp>
#include "floats.hpp"
#include <QtGui/QKeyEvent>
@ -12,7 +13,7 @@
#include <QtGui/QApplication>
#include <QtCore/QDebug>
#include <functional>
namespace std {
template <>
@ -25,6 +26,15 @@ namespace std {
return h1 ^ (h2 << 1);
}
};
class distanceOf2float2s : public std::function<float(float2, float2)>
{
public:
float operator()(float2 a, float2 b)
{
return dist(a, b);
}
};
}
namespace {
@ -35,6 +45,8 @@ namespace {
// return length(v1) < length(v2);
// }
float2 inline float2FromQPointF(const QPointF& p)
{
return float2(p.x(), p.y());
@ -45,6 +57,40 @@ QPointF inline QPointFFromfloat2(const float2& f)
return QPointF(f.x, f.y);
}
inline float dist(const float2& v1, const float2& v2)
{
return sqrt(pow((v2.x - v1.x),2) + pow((v2.y - v1.y),2));
}
QList<Edge*> calculateShortestRoute(const QGraphicsScene* scene,
const Graph<float2>* graph,
const Node* source,
const Node* destination)
{
const float2 s = float2FromQPointF(source->pos());
const float2 d = float2FromQPointF(destination->pos());
const std::vector<float2> shortestPath = dijkstra_shortest_path_to<float2, float>(*graph, s, d, std::distanceOf2float2s());
QList<Edge*> route;
const int lenghtOfRoute = shortestPath.size();
if (lenghtOfRoute < 2)
return route;
for (int i = 0; i < lenghtOfRoute; ++i) {
if (i+1 == lenghtOfRoute)
break;
QGraphicsItem* source_item = scene->itemAt(QPointFFromfloat2(shortestPath[i]));
QGraphicsItem* destination_item = scene->itemAt(QPointFFromfloat2(shortestPath[i+1]));
Node* source_node = dynamic_cast<Node*>(source_item);
Node* destination_node = dynamic_cast<Node*>(destination_item);
Edge* e = source_node->edgeTo(destination_node);
route.append(e);
}
return route;
}
} // anonym namespace
@ -131,6 +177,30 @@ void GraphWidget::keyPressEvent(QKeyEvent *e)
}
break;
}
case Qt::Key_Space: {
for (QList<Edge*>::iterator it = m_route.begin(); it != m_route.end(); ++it)
(*it)->setIsRoute(false);
QList <QGraphicsItem* > selectedItems = scene()->selectedItems();
if (selectedItems.isEmpty())
break;
QGraphicsItem* selectedItem = selectedItems.first();
Node* selectedNode = dynamic_cast<Node*>(selectedItem);
const QPoint global_p = QCursor::pos();
const QPoint widget_p = mapFromGlobal(global_p);
const QPointF scene_p = mapToScene(widget_p);
QGraphicsItem* item_under_mouse = scene()->itemAt(scene_p);
Node* nodeUnderMouse = dynamic_cast<Node*>(item_under_mouse);
if (nodeUnderMouse != 0 && nodeUnderMouse != selectedNode) {
m_route = calculateShortestRoute(scene(), m_graph, selectedNode, nodeUnderMouse);
for (QList<Edge*>::iterator it = m_route.begin(); it != m_route.end(); ++it)
(*it)->setIsRoute(true);
}
}
default:
QGraphicsView::keyPressEvent(e);
}

@ -6,6 +6,7 @@
class float2;
template<class T> class Graph;
class Node;
class Edge;
class GraphWidget : public QGraphicsView
{
@ -37,6 +38,7 @@ private:
void removeEdge(Node* selectedNode, Node* nodeUnderMouse);
Graph<float2>* m_graph;
QList<Edge*> m_route;
};
#endif

@ -2,8 +2,6 @@
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtCore/QTime>
#include <graph/graph.hpp>
#include <graph/graph_xml.hpp>
@ -52,14 +50,31 @@ float2 float2creator(const std::string& line)
inline std::string float2serializer(const float2& f2)
{
return std::to_string_with_precision(f2.x, 3) + " " + std::to_string_with_precision(f2.y, 3);
}
// https://stackoverflow.com/questions/13878373/where-am-i-supposed-to-reimplement-qapplicationnotify-function
class SafeQApplication : public QApplication
{
public:
SafeQApplication(int &argCounter, char ** argVector) : QApplication(argCounter, argVector) {}
private:
bool notify(QObject *receiver_, QEvent *event_)
{
try {
return QApplication::notify(receiver_, event_);
} catch (std::exception &ex) {
std::cerr << "std::exception was caught " << ex.what() << std::endl;
}
return false;
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
SafeQApplication app(argc, argv);
const std::string xml_file = "graph_example.xml";
Graph<float2> g = readGraphFromXML<float2>(xml_file, float2creator);

@ -35,6 +35,17 @@ QList<Edge *> Node::edges() const
return edgeList;
}
Edge* Node::edgeTo(const Node* n) const
{
for (int i = 0; i < edgeList.size(); ++i) {
Edge* e = edgeList.at(i);
if (e->destNode() == n)
return e;
}
return 0;
}
QRectF Node::boundingRect() const
{
qreal adjust = 2;

@ -16,6 +16,7 @@ public:
void addEdge(Edge *edge);
void removeEdge(Edge* edge);
QList<Edge *> edges() const;
Edge* edgeTo(const Node* n) const;
enum { Type = UserType + 1 };
int type() const override { return Type; }
@ -31,7 +32,6 @@ protected:
private:
QList<Edge *> edgeList;
QPointF newPos;
GraphWidget *m_graphWidget;
};

Loading…
Cancel
Save