Commit a48f3fe2 authored by Valentin Platzgummer's avatar Valentin Platzgummer

function handle error solved

parent 7bad89ed
......@@ -16,7 +16,7 @@ namespace OptimisationTools {
* \sa QList
*/
template <typename T>
bool dijkstraAlgorithm(const QList<T> elements, int startIndex, int endIndex, QList<T> &elementPath, double(*distance)(const T &t1, const T &t2)) // don't seperate parameters with new lines or documentation will break
bool dijkstraAlgorithm(const QList<T> elements, int startIndex, int endIndex, QList<T> &elementPath, std::function<double(const T &, const T &)> distance) // don't seperate parameters with new lines or documentation will break
{
if ( elements.isEmpty() || startIndex < 0
|| startIndex >= elements.size() || endIndex < 0
......
......@@ -3,9 +3,11 @@
#include <QObject>
#include <functional>
namespace OptimisationTools {
template <typename T>
bool dijkstraAlgorithm(const QList<T> elements, int startIndex, int endIndex, QList<T> &elementPath, double(*distance)(const T &t1, const T &t2));
bool dijkstraAlgorithm(const QList<T> elements, int startIndex, int endIndex, QList<T> &elementPath, std::function<double(const T &, const T &)> distance);
}
#endif // OPTIMISATIONTOOLS_H
......@@ -33,9 +33,9 @@ namespace PlanimetryCalculus {
void rotateReference(QLineF &line, double alpha);
//void rotateReference(QPolygonF &polygon, double alpha);
QPointF rotateReturn(QPointF point, double alpha);
QPointFList rotateReturn(QPointFList points, double alpha);
QLineF rotateReturn(QLineF line, double alpha);
QPointF rotateReturn(QPointF point, double alpha);
QPointFList rotateReturn(QPointFList points, double alpha);
QLineF rotateReturn(QLineF line, double alpha);
//QPolygonF rotateReturn(QPolygonF &polygon, double alpha);
bool intersects(const Circle &circle1, const Circle &circle2);
......
......@@ -175,11 +175,11 @@ namespace PolygonCalculus {
QPointF currentVertex = walkerPoly->value(startIndex);
QPointF startVertex = currentVertex;
// possible nextVertex (if no intersection between currentVertex and protoVertex with crossPoly)
int nextVertexIndex = nextVertexIndex(walkerPoly->size(), startIndex);
QPointF protoNextVertex = walkerPoly->value(nextVertexIndex);
int nextVertexNumber = nextVertexIndex(walkerPoly->size(), startIndex);
QPointF protoNextVertex = walkerPoly->value(nextVertexNumber);
bool switchHappenedPreviously = false; // means switch between crossPoly and walkerPoly
while (1) {
//qDebug("nextVertexIndex: %i", nextVertexIndex);
//qDebug("nextVertexNumber: %i", nextVertexNumber);
joinedPolygon.append(currentVertex);
QLineF walkerPolySegment;
......@@ -221,7 +221,7 @@ namespace PolygonCalculus {
currentVertex = protoCurrentVertex;
QPair<int, int> neighbours = neighbourList.value(minDistIndex);
protoNextVertex = crossPoly->value(neighbours.second);
nextVertexIndex = neighbours.second;
nextVertexNumber = neighbours.second;
// switch walker and cross poly
const QPolygonF *temp = walkerPoly;
......@@ -230,17 +230,17 @@ namespace PolygonCalculus {
switchHappenedPreviously = true;
} else {
currentVertex = walkerPoly->value(nextVertexIndex);
nextVertexIndex = nextVertexIndex(walkerPoly->size(), nextVertexIndex);
protoNextVertex = walkerPoly->value(nextVertexIndex);
currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber);
switchHappenedPreviously = false;
}
} else {
currentVertex = walkerPoly->value(nex bool containsPath (const QPointF &c1, const QPointF &c2, QPolygonF polygon);tVertexIndex);
nextVertexIndex = nextVertexIndex(walkerPoly->size(), nextVertexIndex);
protoNextVertex = walkerPoly->value(nextVertexIndex);
currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber);
}
if (currentVertex == startVertex) {
......@@ -487,7 +487,7 @@ namespace PolygonCalculus {
if ( polygon.containsPoint(startVertex, Qt::FillRule::OddEvenFill)
&& polygon.containsPoint(endVertex, Qt::FillRule::OddEvenFill)) {
// lambda
auto distance = [polygon](const QPointF &p1, const QPointF &p2){
auto distance = [polygon](const QPointF &p1, const QPointF &p2) -> double {
if (containsPath(polygon, p1, p2)){
double dx = p1.x()-p2.x();
double dy = p1.y()-p2.y();
......@@ -503,10 +503,7 @@ namespace PolygonCalculus {
elementList.append(polygon[i]);
}
OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distance);
return OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distance);
} else {
return false;
}
......
#include "SphereCalculus.h"
SphereCalculus::SphereCalculus(const SphereCalculus &other, QObject *parent)
: QObject (parent)
{
*this = other;
}
SphereCalculus &SphereCalculus::operator=(const SphereCalculus &other)
{
setEpsilonMeter(other.epsilonMeter());
return *this;
}
void SphereCalculus::setEpsilonMeter(double epsilon)
{
if (epsilon > 0) {
_epsilonMeter = epsilon;
}
}
double SphereCalculus::epsilonMeter() const
{
return _epsilonMeter;
}
/*!
* \fn bool SphereCalculus::dijkstraPath(const QList<QGeoCoordinate> &polygon, const QGeoCoordinate &c1, const QGeoCoordinate &c2, QList<QGeoCoordinate> &dijkstraPath)
* Calculates the shortest path (inside \a polygon) between \a start and \a end.
* The \l {Dijkstra Algorithm} is used to find the shorest path.
* Stores the result inside \a dijkstraPath when sucessfull.
* Stores error messages in \a errorString.
* Returns \c true if successful, \c false else.
*
* \sa QList
*/
SphereCalculus::DijkstraError SphereCalculus::dijkstraPath(const QList<QGeoCoordinate> &polygon, const QGeoCoordinate &start, const QGeoCoordinate &end, QList<QGeoCoordinate> &dijkstraPath)
{
if ( isSimplePolygon(polygon) ) {
return SphereCalculus::DijkstraError::NotSimplePolygon;
}
// Each QGeoCoordinate gets stuff into a Node
/// @param distance is the distance between the Node and it's predecessor
struct Node{
QGeoCoordinate coordinate;
double distance = std::numeric_limits<qreal>::infinity();
Node* predecessorNode = nullptr;
};
// The list with all Nodes (start, end + poly.path())
QList<Node> nodeList;
// This list will be initalized with (pointer to) all elements of nodeList.
// Elements will be successively remove during the execution of the Dijkstra Algorithm.
QList<Node*> workingSet;
// initialize nodeList_maxAltitude
// start cooridnate
Node startNode;
startNode.coordinate = start;
startNode.distance = 0;
nodeList.append(startNode);
//poly cooridnates
for (int i = 0; i < polygon.size(); i++) {
Node node;
node.coordinate = polygon[i];
nodeList.append(node);
}
//end coordinate
Node endNode;
endNode.coordinate = end;
nodeList.append(endNode);
// initialize working set
for (int i = 0; i < nodeList.size(); i++) {
Node* nodePtr = &nodeList[i];
workingSet.append(nodePtr);
}
// Dijkstra Algorithm
// https://de.wikipedia.org/wiki/Dijkstra-Algorithmus
while (workingSet.size() > 0) {
// serach Node with minimal distance
double minDist = std::numeric_limits<qreal>::infinity();
int minDistIndex = 0;
for (int i = 0; i < workingSet.size(); i++) {
Node* node = workingSet.value(i);
double dist = node->distance;
if (dist < minDist) {
minDist = dist;
minDistIndex = i;
}
}
Node* u = workingSet.takeAt(minDistIndex);
//update distance
for (int i = 0; i < workingSet.size(); i++) {
Node* v = workingSet[i];
// is neighbour? dist == infinity if no neihbour
double dist = distanceInsidePolygon(u->coordinate, v->coordinate, polygon);
// is ther a alternative path which is shorter?QList<QGeoCoordinate>
double alternative = u->distance + dist;
if (alternative < v->distance) {
v->distance = alternative;
v->predecessorNode = u;
}
}
}
// end Djikstra Algorithm
// reverse assemble path
Node* Node = &nodeList.last();
while (1) {
dijkstraPath.prepend(Node->coordinate);
//Update Node
Node = Node->predecessorNode;
if (Node == nullptr) {
if (dijkstraPath[0].distanceTo(start) < _epsilonMeter)// check if starting point was reached
break;
qWarning("WimaArea::dijkstraPath(): Error, no path found!\n");
return SphereCalculus::DijkstraError::NoPathFound;
}
}
return SphereCalculus::DijkstraError::PathFound;
}
......
#ifndef SphereCalculus_H
#define SphereCalculus_H
#endif // SphereCalculus_H
#include <QObject>
#include <QGeoCoordinate>
......@@ -8,46 +9,11 @@
#include "QGCGeo.h"
// Abstract class providing methods to do calculations on objects located on a sphere (e.g. earth)
class SphereCalculus : public QObject
{
Q_OBJECT
public:
SphereCalculus(QObject *parent = nullptr);
SphereCalculus(const SphereCalculus &other, QObject *parent = nullptr);
SphereCalculus &operator=(const SphereCalculus &other);
typedef QPair<QGeoCoordinate, QGeoCoordinate> Line;
enum JoinPolygonError { NotSimplePolygon1, PolygonJoined, NotSimplePolygon2, Disjoint, PathSizeLow};
enum IntersectionType { NoIntersection, EdgeIntersection, InteriorIntersection, Error};
enum DijkstraError { NoPathFound, PathFound, NotSimplePolygon};
// Property setters
void setEpsilonMeter(double epsilon);
// Property getters
double epsilonMeter() const;
// Member Methodes
#include "PlanimetryCalculus.h"
DijkstraError dijkstraPath (const QList<QGeoCoordinate> &polygon, const QGeoCoordinate& start,
const QGeoCoordinate& end, QList<QGeoCoordinate>& dijkstraPath);
namespace SphereCalculus {
}
signals:
public slots:
private:
double _epsilonMeter; // The accuracy used for distance calculations (unit: m).
};
#endif // SphereCalculus_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment