summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Boeckel <MathStuf@gmail.com>2009-04-04 18:20:58 -0400
committerBen Boeckel <MathStuf@gmail.com>2009-04-04 18:20:58 -0400
commitce9e1a24c5ae67abbee16d02a43e42903ad644af (patch)
tree10606632bf0cf1ae6d3c1105a1daba1ba1727be7
parente510879baf385b350bd57e6d719c9790e223bb2f (diff)
Find the closest spot to a point code
-rw-r--r--sigmodr/widgets/mapeditor/WorldMapPlacement.cpp40
-rw-r--r--sigmodr/widgets/mapeditor/WorldMapPlacement.h1
2 files changed, 38 insertions, 3 deletions
diff --git a/sigmodr/widgets/mapeditor/WorldMapPlacement.cpp b/sigmodr/widgets/mapeditor/WorldMapPlacement.cpp
index 6cd55f2f..cf7d9ea0 100644
--- a/sigmodr/widgets/mapeditor/WorldMapPlacement.cpp
+++ b/sigmodr/widgets/mapeditor/WorldMapPlacement.cpp
@@ -21,6 +21,9 @@
// Qt includes
#include <QtCore/QQueue>
+// Standard includes
+#include <cmath>
+
using namespace Sigmodr::Widgets;
bool WorldMapPlacement::m_cacheGood = false;
@@ -84,13 +87,16 @@ QPoint WorldMapPlacement::find(const QPoint& point)
const QPoint last = polygon[i - 1];
const QPoint cur = polygon[i];
const QPoint next = polygon[(i + 1) % polygon.size()];
+ QRectF rect(QPoint(), m_size);
if (((point.x() - last.x()) * (point.x() - cur.x())) < 0)
{
- // TODO: Crosses the vertical axis from last -- cur
+ rect.moveCenter(QPoint(point.x(), cur.y() + ((((point.y() < cur.y()) ? 1 : -1) * m_size.height()) / 2)));
+ best = closer(best, rect.toRect(), point);
}
else if (((point.y() - last.y()) * (point.y() - cur.y())) < 0)
{
- // TODO: Crosses the horizontal axis from last -- cur
+ rect.moveCenter(QPoint(cur.x() + ((((point.x() < cur.x()) ? 1 : -1) * m_size.width()) / 2), point.y()));
+ best = closer(best, rect.toRect(), point);
}
Corner corner = Invalid;
if ((cur.x() < last.x()) && (cur.y() < next.y()))
@@ -103,7 +109,24 @@ QPoint WorldMapPlacement::find(const QPoint& point)
corner = BottomLeft;
if (corner != Invalid)
{
- // TODO: Corner is concave
+ switch (corner)
+ {
+ case TopLeft:
+ rect.moveTopLeft(cur);
+ break;
+ case TopRight:
+ rect.moveTopRight(cur);
+ break;
+ case BottomRight:
+ rect.moveBottomRight(cur);
+ break;
+ case BottomLeft:
+ rect.moveBottomLeft(cur);
+ break;
+ default:
+ break;
+ }
+ best = closer(best, rect.toRect(), point);
}
}
}
@@ -169,3 +192,14 @@ QPolygon WorldMapPlacement::mergePolygons(const QPolygon& polygon1, const QPolyg
// TODO: merge the polygons
return polygon1;
}
+
+QRect WorldMapPlacement::closer(const QRect& rect1, const QRect& rect2, const QPoint& point)
+{
+ if (rect1.isNull())
+ return rect2;
+ const QPoint rect1Point = rect1.center() - point;
+ const QPoint rect2Point = rect2.center() - point;
+ const int rect1Dist = pow(rect1Point.x(), 2) + pow(rect1Point.y(), 2);
+ const int rect2Dist = pow(rect2Point.x(), 2) + pow(rect2Point.y(), 2);
+ return (rect1Dist < rect2Dist) ? rect1 : rect2;
+}
diff --git a/sigmodr/widgets/mapeditor/WorldMapPlacement.h b/sigmodr/widgets/mapeditor/WorldMapPlacement.h
index ed07d6f2..19c5e66a 100644
--- a/sigmodr/widgets/mapeditor/WorldMapPlacement.h
+++ b/sigmodr/widgets/mapeditor/WorldMapPlacement.h
@@ -53,6 +53,7 @@ class SIGMODRWIDGETS_NO_EXPORT WorldMapPlacement
void finalize();
bool touches(const QPolygon& polygon1, const QPolygon& polygon2);
QPolygon mergePolygons(const QPolygon& polygon1, const QPolygon& polygon2);
+ QRect closer(const QRect& rect1, const QRect& rect2, const QPoint& point);
static bool m_cacheGood;
static QSize m_size;