# HG changeset patch # User Teemu Piippo # Date 1630014932 -10800 # Node ID b54b350dff5d79317a473dd81d817da90b52b2b2 # Parent 000781318c36afaebefa024e272a5586d512af02 Show concave polygons as red while drawing diff -r 000781318c36 -r b54b350dff5d src/geometry.cpp --- a/src/geometry.cpp Fri Jul 30 01:28:39 2021 +0300 +++ b/src/geometry.cpp Fri Aug 27 00:55:32 2021 +0300 @@ -1,5 +1,7 @@ #include #include "geometry.h" +#include "ring.h" +#include "maths.h" /** * @brief Computes line-plane intersection @@ -196,3 +198,24 @@ glm::vec2{rectangle.right(), rectangle.bottom()} }; } + +bool geom::convex(const std::vector& polygon) +{ + const int n = polygon.size(); + auto polygonRing = iter::ring(polygon, n); + std::vector crosses; + crosses.resize(n); + for (int i = 0; i < n; i += 1) + { + crosses[i] = glm::cross(polygonRing[i - 1] - polygonRing[i], polygonRing[i + 1] - polygonRing[i]); + } + for (int i = 0; i < n - 1; i += 1) + { + const float dotp = glm::dot(crosses[0], crosses[i + 1]); + if (dotp < 0 or qFuzzyIsNull(dotp)) + { + return false; + } + } + return true; +} diff -r 000781318c36 -r b54b350dff5d src/geometry.h --- a/src/geometry.h Fri Jul 30 01:28:39 2021 +0300 +++ b/src/geometry.h Fri Aug 27 00:55:32 2021 +0300 @@ -93,6 +93,7 @@ LineSegment2D bottom(const QRectF& rectangle); LineSegment2D left(const QRectF& rectangle); LineSegment2D right(const QRectF& rectangle); + bool convex(const std::vector& polygon); struct ScalingExtract { glm::vec3 scaling; diff -r 000781318c36 -r b54b350dff5d src/maths.h --- a/src/maths.h Fri Jul 30 01:28:39 2021 +0300 +++ b/src/maths.h Fri Aug 27 00:55:32 2021 +0300 @@ -72,7 +72,32 @@ } constexpr double infinity = std::numeric_limits::infinity(); constexpr long double pi = M_PIl; - + // Returns the minimum value of a container + template + inline auto nmin(T&& values) + { + auto it = std::begin(values); + auto result_p = it; + for (++it; it != std::end(values); ++it) + { + if (*it < *result_p) + result_p = it; + } + return *result_p; + } + // Returns the maximum value of a container + template + inline auto nmax(T&& values) + { + auto it = std::begin(values); + auto result_p = it; + for (++it; it != std::end(values); ++it) + { + if (*it > *result_p) + result_p = it; + } + return *result_p; + } /* * Returns the empty sum. (recursion base) */ diff -r 000781318c36 -r b54b350dff5d src/tools/drawtool.cpp --- a/src/tools/drawtool.cpp Fri Jul 30 01:28:39 2021 +0300 +++ b/src/tools/drawtool.cpp Fri Aug 27 00:55:32 2021 +0300 @@ -10,6 +10,7 @@ static const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}; static const QPen pointPen = {QBrush{Qt::black}, 2.0}; static const QBrush polygonBrush = {QColor{64, 255, 128, 192}}; +static const QBrush badPolygonBrush = {QColor{255, 96, 96, 192}}; DrawTool::DrawTool(QObject* parent) : BaseTool{parent} {} @@ -83,6 +84,10 @@ { this->previewPolygon.resize(this->polygon.size() + 1); this->previewPolygon.back() = this->previewPoint; + if (this->previewPolygon.size() > 2) + { + this->isconcave = not geom::convex(this->previewPolygon); + } } void DrawTool::reset() @@ -92,7 +97,7 @@ void DrawTool::overpaint(Canvas* canvas, QPainter* painter) const { - painter->setBrush(::polygonBrush); + painter->setBrush(this->isconcave ? ::badPolygonBrush : ::polygonBrush); painter->setPen(::polygonPen); canvas->drawWorldPolygon(painter, this->previewPolygon); painter->setBrush(::pointBrush); diff -r 000781318c36 -r b54b350dff5d src/tools/drawtool.h --- a/src/tools/drawtool.h Fri Jul 30 01:28:39 2021 +0300 +++ b/src/tools/drawtool.h Fri Aug 27 00:55:32 2021 +0300 @@ -19,5 +19,6 @@ std::vector polygon; std::vector previewPolygon; glm::vec3 previewPoint; + bool isconcave = false; void updatePreviewPolygon(); };