From 858b7058fb299c91c8f7590ab2eb9739dae1f1b7 Mon Sep 17 00:00:00 2001 From: Daniel2000815 Date: Thu, 8 Feb 2024 13:36:13 +0100 Subject: [PATCH 1/2] Added closest(line, line) and test --- TEST_Geometry2D.cpp | 33 +++++++++++++++++++++++++++++++++ olcUTIL_Geometry2D.h | 28 ++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/TEST_Geometry2D.cpp b/TEST_Geometry2D.cpp index fbdb6ee..cbc4c87 100644 --- a/TEST_Geometry2D.cpp +++ b/TEST_Geometry2D.cpp @@ -132,6 +132,26 @@ class Test_Geometry2D : public olc::PixelGameEngine return std::visit(dispatch, s1, s2); } + olc::vf2d CheckClosest(const ShapeWrap& s1, const ShapeWrap& s2) + { + const auto dispatch = overloads{ + [](const auto& lhs, const auto& rhs) + { + return closest(make_internal(lhs), make_internal(rhs)); + }, + // Discard not implemented + [](const Ray&, const auto&) { return olc::vf2d{}; }, + [](const auto&, const Ray&) {return olc::vf2d{}; }, + [](const Ray&, const Ray&) {return olc::vf2d{}; }, + [](const Line&, const Rect&) {return olc::vf2d{}; }, + [](const Rect&, const Rect&) {return olc::vf2d{}; }, + [](const Circle&, const Rect&) {return olc::vf2d{}; }, + [](const Triangle&, const Rect&) {return olc::vf2d{}; } + }; + + return std::visit(dispatch, s1, s2); + } + std::vector CheckIntersects(const ShapeWrap& s1, const ShapeWrap& s2) { const auto dispatch = overloads{ @@ -294,6 +314,7 @@ class Test_Geometry2D : public olc::PixelGameEngine std::vector vContains; std::vector vOverlaps; std::vector vIntersections; + std::vector vClosestsPoints; if (nSelectedShapeIndex < vecShapes.size()) { for (size_t i = 0; i < vecShapes.size(); i++) @@ -310,6 +331,13 @@ class Test_Geometry2D : public olc::PixelGameEngine if (CheckOverlaps(vecShapes[nSelectedShapeIndex], vTargetShape)) vOverlaps.push_back(i); + + olc::v_2d c = CheckClosest(vecShapes[nSelectedShapeIndex], vTargetShape); + if (c.mag() > 0.f) { + vClosestsPoints.push_back(c); + vClosestsPoints.push_back(CheckClosest(vTargetShape, vecShapes[nSelectedShapeIndex])); + } + } } @@ -369,6 +397,11 @@ class Test_Geometry2D : public olc::PixelGameEngine for (const auto& intersection : vIntersections) FillCircle(intersection, 3, olc::RED); + // Draw Closests + for (auto i = 0; i < vClosestsPoints.size()/2; i++) + DrawLine(vClosestsPoints[2 * i], vClosestsPoints[2 * i + 1], olc::DARK_GREY); + + if (bRayMode) { DrawShape(ray1, olc::CYAN); diff --git a/olcUTIL_Geometry2D.h b/olcUTIL_Geometry2D.h index 7e3be8a..8b61504 100644 --- a/olcUTIL_Geometry2D.h +++ b/olcUTIL_Geometry2D.h @@ -191,6 +191,7 @@ #include #include #include +#include #ifndef OLC_V2D_TYPE #define OLC_V2D_TYPE @@ -895,8 +896,31 @@ namespace olc::utils::geom2d template inline olc::v_2d closest(const line& l1, const line& l2) { - // TODO: - return {}; + auto V1 = l1.end - l1.start; + auto V2 = l2.end - l2.start; + auto V21 = l2.start - l1.start; + + auto v22 = V2.dot(V2); + auto v11 = V1.dot(V1); + auto v21 = V2.dot(V1); + auto v21_1 = V21.dot(V1); + auto v21_2 = V21.dot(V2); + auto denom = v21 * v21 - v22 * v11; + + float s, t; + if (denom == 0.f) { + s = 0.f; + t = (v11 * s - v21_1) / v21; + } + else { + s = (v21_2 * v21 - v22 * v21_1) / denom; + t = (-v21_1 * v21 + v11 * v21_2) / denom; + } + + s = std::max(std::min(s, 1.f), 0.f); + t = std::max(std::min(t, 1.f), 0.f); + + return l1.start + s * V1; } // closest(r,l) From 67c0ace208da1d8957833d468860064345ec4258 Mon Sep 17 00:00:00 2001 From: Daniel2000815 Date: Thu, 8 Feb 2024 16:19:06 +0100 Subject: [PATCH 2/2] Remove iostream include --- olcUTIL_Geometry2D.h | 1 - 1 file changed, 1 deletion(-) diff --git a/olcUTIL_Geometry2D.h b/olcUTIL_Geometry2D.h index 8b61504..6add43e 100644 --- a/olcUTIL_Geometry2D.h +++ b/olcUTIL_Geometry2D.h @@ -191,7 +191,6 @@ #include #include #include -#include #ifndef OLC_V2D_TYPE #define OLC_V2D_TYPE