Commit 46eb801f authored by Valentin Platzgummer's avatar Valentin Platzgummer

dijkstra balzing fast, not fully tested though, bottleneck QLineF::intersect()

parent 1b0cf6ce
......@@ -81,12 +81,6 @@ namespace OptimisationTools {
}
}
qDebug() << "nodeList" ;
for (auto node : nodeList) {
qDebug() << "predecessor: " << node.predecessorIndex;
qDebug() << "distance: " << node.distance;
}
}
// end Djikstra Algorithm
......
......@@ -687,6 +687,73 @@ angle
return intersects(circle, line, intersectionPoints, type, true /* calculate intersection points*/);
}
bool intersectsFast(const QPolygonF &polygon, const QLineF &line)
{
for (int i = 0; i < polygon.size()-1; ++i) {
QLineF polygonSegment(polygon[i], polygon[i+1]);
if(QLineF::BoundedIntersection == line.intersect(polygonSegment, nullptr))
return true;
}
return false;
}
// bool intersectsFast(const QLineF &line1, const QLineF &line2, QPointF &intersectionPt)
// {
// if (line1.isNull() || line2.isNull()){
// return false;
// }
// // determine line equations y = kx+d
// double dx1 = line1.dx();
// double dy1 = line1.dy();
// double k1;
// double d1 = 0;
// if (qFuzzyIsNull(dx1)) {
// k1 = std::numeric_limits<double>::infinity();
// } else {
// k1 = dy1/dx1;
// d1 = line1.y1()-k1*line1.x1();
// }
// double dx2 = line2.dx();
// double dy2 = line2.dy();
// double k2;
// double d2 = 0;
// if (qFuzzyIsNull(dx2)) {
// k2 = std::numeric_limits<double>::infinity();
// } else {
// k2 = dy2/dx2;
// d2 = line2.y1()-k2*line2.x1();
// }
// if ( !qFuzzyCompare(k1, std::numeric_limits<double>::infinity())
// && !qFuzzyCompare(k1, std::numeric_limits<double>::infinity())) {
// double dk = k2-k1;
// double dd = d2-d1;
// if (qFuzzyIsNull(dk)) { // lines parallel
// if (qFuzzyIsNull(dd)) { // lines colinear
// if ( ((line1.x1() >= line2.x1()) && ((line1.x1() <= line2.x2())))
// || ((line1.x2() >= line2.x1()) && ((line1.x2() <= line2.x2()))) ) // intersect?
// return true;
// return false;
// }
// return false;
// }
// double x_intersect = -dd/dk;
// if (((x_intersect >= line2.x1()) && ((line1.x1() <= line2.x2())))
// }
// return true;
// }
......
......@@ -59,11 +59,15 @@ namespace PlanimetryCalculus {
bool intersects(const QLineF &line1, const QLineF &line2);
bool intersects(const QLineF &line1, const QLineF &line2, QPointF &intersectionPt);
bool intersects(const QLineF &line1, const QLineF &line2, QPointF &intersectionPt, IntersectType &type);
// bool intersectsFast(const QLineF &line1, const QLineF &line2, QPointF &intersectionPt, IntersectType &type);
bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFVector &intersectionList);
bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFVector &intersectionList, IntersectVector &typeList);
bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFVector &intersectionList, NeighbourVector &neighbourList);
bool intersects(const QPolygonF &polygon, const QLineF &line, QPointFVector &intersectionList, NeighbourVector &neighbourList, IntersectVector &typeList);
bool intersectsFast(const QPolygonF &polygon, const QLineF &line);
bool contains(const QLineF &line, const QPointF &point);
bool contains(const QLineF &line, const QPointF &point, IntersectType &type);
bool contains(const QPolygonF &polygon, const QPointF &point);
......
......@@ -32,22 +32,10 @@ namespace PolygonCalculus {
if ( !polygon.containsPoint(c1, Qt::FillRule::OddEvenFill)
|| !polygon.containsPoint(c2, Qt::FillRule::OddEvenFill))
return false;
QVector<QPointF> intersectionList;
QLineF line;
line.setP1(c1);
line.setP2(c2);
PlanimetryCalculus::IntersectVector intersectTypeList;
bool retValue = PlanimetryCalculus::intersects(polygon, line, intersectionList, intersectTypeList);
if (retValue) {
for (int i = 0; i < intersectTypeList.size(); i++) {
PlanimetryCalculus::IntersectType type = intersectTypeList[i];
if ( type == PlanimetryCalculus::EdgeEdgeIntersection
|| type == PlanimetryCalculus::Error)
return false;
}
}
QLineF line(c1, c2);
if (PlanimetryCalculus::intersectsFast(polygon, line))
return false;
return true;
} else {
return false;
......@@ -475,15 +463,13 @@ namespace PolygonCalculus {
return;
}
bool shortestPath(QPolygonF polygon,const QPointF &startVertex, const QPointF &endVertex, QVector<QPointF> &shortestPath)
bool shortestPath(const QPolygonF &polygon,const QPointF &startVertex, const QPointF &endVertex, QVector<QPointF> &shortestPath)
{
using namespace PlanimetryCalculus;
offsetPolygon(polygon, 0.01); // solves numerical errors
if ( contains(polygon, startVertex)
&& contains(polygon, endVertex)) {
// lambda
QPolygonF polygon2 = polygon;
offsetPolygon(polygon2, 0.01); // solves numerical errors
QPolygonF bigPolygon(polygon);
offsetPolygon(bigPolygon, 0.1); // solves numerical errors
if ( bigPolygon.containsPoint(startVertex, Qt::FillRule::OddEvenFill)
&& bigPolygon.containsPoint(endVertex, Qt::FillRule::OddEvenFill)) {
QVector<QPointF> elementList;
elementList.append(startVertex);
......@@ -492,14 +478,14 @@ namespace PolygonCalculus {
const int listSize = elementList.size();
std::function<double(const int, const int)> distanceDij = [polygon2, elementList](const int ind1, const int ind2) -> double {
std::function<double(const int, const int)> distanceDij = [bigPolygon, elementList](const int ind1, const int ind2) -> double {
QPointF p1 = elementList[ind1];
QPointF p2 = elementList[ind2];
double dist = std::numeric_limits<double>::infinity();
if (containsPath(polygon2, p1, p2)){
if (containsPathFast(bigPolygon, p1, p2)){ // containsPathFast can be used since all points are inside bigPolygon
double dx = p1.x()-p2.x();
double dy = p1.y()-p2.y();
dist = (dx*dx)+(dy*dy); // sqrt not necessary
dist = sqrt((dx*dx)+(dy*dy));
}
return dist;
......@@ -561,5 +547,20 @@ namespace PolygonCalculus {
bool containsPathFast(QPolygonF polygon, const QPointF &c1, const QPointF &c2)
{
if ( !polygon.isEmpty()) {
QLineF line(c1, c2);
if (PlanimetryCalculus::intersectsFast(polygon, line))
return false;
return true;
} else {
return false;
}
}
} // end PolygonCalculus namespace
......@@ -26,9 +26,12 @@ namespace PolygonCalculus {
void reversePath (QPointFList &path);
void reversePath (QPointFVector &path);
void offsetPolygon (QPolygonF &polygon, double offset);
// returns true if the line c1-c2 is fully inside the polygon
bool containsPath (QPolygonF polygon, const QPointF &c1, const QPointF &c2);
// same as containsPath(), but works only if c1 and c2 are inside the polygon!
bool containsPathFast (QPolygonF polygon, const QPointF &c1, const QPointF &c2);
void decomposeToConvex (const QPolygonF &polygon, QList<QPolygonF> &convexPolygons);
bool shortestPath (QPolygonF polygon, const QPointF &startVertex, const QPointF &endVertex, QVector<QPointF> &shortestPath);
bool shortestPath (const QPolygonF &polygon, const QPointF &startVertex, const QPointF &endVertex, QVector<QPointF> &shortestPath);
QPolygonF toQPolygonF(const QVector3DList &polygon);
QPolygonF toQPolygonF(const QPointFList &polygon);
......
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