1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 14:53:21 +02:00

A more robust RectC to RectD algorithm

This commit is contained in:
Martin Tůma 2020-12-12 10:19:48 +01:00
parent 22fb6071f7
commit 4cef089c81
3 changed files with 36 additions and 26 deletions

View File

@ -24,6 +24,13 @@ public:
{return Coordinates((_tl.lon() + _br.lon()) / 2.0, {return Coordinates((_tl.lon() + _br.lon()) / 2.0,
(_tl.lat() + _br.lat()) / 2.0);} (_tl.lat() + _br.lat()) / 2.0);}
double width() const
{
double res = right() - left();
return (left() > right()) ? 360.0 - res : res;
}
double height() const {return (top() - bottom());}
double top() const {return _tl.lat();} double top() const {return _tl.lat();}
double bottom() const {return _br.lat();} double bottom() const {return _br.lat();}
double left() const {return _tl.lon();} double left() const {return _tl.lon();}

View File

@ -1,3 +1,4 @@
#include <cmath>
#include "common/rectc.h" #include "common/rectc.h"
#include "projection.h" #include "projection.h"
#include "rectd.h" #include "rectd.h"
@ -48,19 +49,19 @@ static void growRect(const Projection &proj, const PointD &p, RectC &rect)
RectD::RectD(const RectC &rect, const Projection &proj, int samples) RectD::RectD(const RectC &rect, const Projection &proj, int samples)
{ {
RectD prect; RectD prect;
double dx = (rect.right() - rect.left()) / samples;
double dy = (rect.top() - rect.bottom()) / samples;
growRect(proj, rect.topLeft(), prect); if (rect.isValid()) {
double dx = rect.width() / samples;
double dy = rect.height() / samples;
growRect(proj, rect.topLeft(), prect);
if (dx > 0) {
for (int i = 0; i <= samples; i++) { for (int i = 0; i <= samples; i++) {
double x = rect.left() + i * dx; double x = remainder(rect.left() + i * dx, 360.0);
growRect(proj, Coordinates(x, rect.bottom()), prect); growRect(proj, Coordinates(x, rect.bottom()), prect);
growRect(proj, Coordinates(x, rect.top()), prect); growRect(proj, Coordinates(x, rect.top()), prect);
} }
}
if (dy > 0) {
for (int i = 0; i <= samples; i++ ) { for (int i = 0; i <= samples; i++ ) {
double y = rect.bottom() + i * dy; double y = rect.bottom() + i * dy;
growRect(proj, Coordinates(rect.left(), y), prect); growRect(proj, Coordinates(rect.left(), y), prect);
@ -73,26 +74,26 @@ RectD::RectD(const RectC &rect, const Projection &proj, int samples)
RectC RectD::toRectC(const Projection &proj, int samples) const RectC RectD::toRectC(const Projection &proj, int samples) const
{ {
RectC ret; if (!isValid())
double dx = (right() - left()) / samples; return RectC();
double dy = (top() - bottom()) / samples;
growRect(proj, topLeft(), ret); RectC rect;
double dx = width() / samples;
double dy = height() / samples;
if (dx > 0) { growRect(proj, topLeft(), rect);
for (int i = 0; i <= samples; i++) {
double x = left() + i * dx; for (int i = 0; i <= samples; i++) {
growRect(proj, PointD(x, bottom()), ret); double x = left() + i * dx;
growRect(proj, PointD(x, top()), ret); growRect(proj, PointD(x, bottom()), rect);
} growRect(proj, PointD(x, top()), rect);
}
if (dy > 0) {
for (int i = 0; i <= samples; i++ ) {
double y = bottom() + i * dy;
growRect(proj, PointD(left(), y), ret);
growRect(proj, PointD(right(), y), ret);
}
} }
return ret; for (int i = 0; i <= samples; i++ ) {
double y = bottom() + i * dy;
growRect(proj, PointD(left(), y), rect);
growRect(proj, PointD(right(), y), rect);
}
return rect;
} }

View File

@ -35,7 +35,9 @@ public:
&& p.y() >= bottom());} && p.y() >= bottom());}
bool isNull() const {return _tl.isNull() && _br.isNull();} bool isNull() const {return _tl.isNull() && _br.isNull();}
bool isValid() const {return !(_tl.isNull() || _br.isNull());} bool isValid() const
{return (_tl.isValid() && _br.isValid()
&& _tl.x() != _br.x() && _tl.y() != _br.y());}
RectC toRectC(const Projection &proj, int samples = 100) const; RectC toRectC(const Projection &proj, int samples = 100) const;