Skip to content

Commit 2676412

Browse files
author
Illia
committed
Implemented project(c,t) (project circle onto triangle via a ray). Updated a demo for testing
1 parent 66df055 commit 2676412

2 files changed

Lines changed: 85 additions & 5 deletions

File tree

TEST_Geometry2D.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "third_party/olcPGEX_QuickGUI.h"
99

1010
#include <variant>
11+
#include <optional>
1112

1213

1314
using namespace olc::utils::geom2d;
@@ -156,6 +157,29 @@ class Test_Geometry2D : public olc::PixelGameEngine
156157
return std::visit(dispatch, s1, s2);
157158
}
158159

160+
std::optional<olc::v_2d<float>> CheckProject(const ShapeWrap& s1, const ShapeWrap& s2, const ShapeWrap& s3)
161+
{
162+
const auto dispatch = overloads{
163+
164+
[](const auto& s1, const auto& s2, const auto& s3)
165+
{
166+
return std::optional<olc::v_2d<float>>{};
167+
},
168+
169+
[](const Circle& s1, const Rect& s2, const Ray& s3)
170+
{
171+
return project(make_internal(s1), make_internal(s2), make_internal(s3));
172+
},
173+
174+
[](const Circle& s1, const Triangle& s2, const Ray& s3)
175+
{
176+
return project(make_internal(s1), make_internal(s2), make_internal(s3));
177+
}
178+
};
179+
180+
return std::visit(dispatch, s1, s2, s3);
181+
}
182+
159183
std::optional<ray<float>> CheckReflect(const olc::utils::geom2d::ray<float>& s1, const ShapeWrap& s2)
160184
{
161185
const auto dispatch = overloads{
@@ -319,6 +343,9 @@ class Test_Geometry2D : public olc::PixelGameEngine
319343

320344

321345
bool bRayMode = false;
346+
std::vector<std::optional<olc::v_2d<float>>> projected_circle_left_ray;
347+
std::vector<std::optional<olc::v_2d<float>>> projected_circle_right_ray;
348+
322349
if (GetMouse(1).bHeld)
323350
{
324351
// Enable Ray Mode
@@ -344,6 +371,15 @@ class Test_Geometry2D : public olc::PixelGameEngine
344371
vIntersections.insert(vIntersections.end(), vPoints3.begin(), vPoints3.end());
345372

346373

374+
for (const auto& shape : vecShapes)
375+
{
376+
if(std::holds_alternative<Rect>(shape) || std::holds_alternative<Triangle>(shape))
377+
{
378+
projected_circle_left_ray.push_back(CheckProject(Circle{ { { 130.0f, 20.0f }, {150.0f, 20.0f} } }, shape, ray1));
379+
projected_circle_right_ray.push_back(CheckProject(Circle{ { { 130.0f, 20.0f }, {150.0f, 20.0f} } }, shape, ray2));
380+
}
381+
}
382+
347383
}
348384

349385
// Draw All Shapes
@@ -373,6 +409,22 @@ class Test_Geometry2D : public olc::PixelGameEngine
373409
{
374410
DrawShape(ray1, olc::CYAN);
375411
DrawShape(ray2, olc::CYAN);
412+
413+
for(const auto& projection : projected_circle_left_ray)
414+
{
415+
if (projection.has_value())
416+
{
417+
DrawCircle(projection.value(), 20.0f, olc::CYAN);
418+
}
419+
}
420+
421+
for (const auto& projection : projected_circle_right_ray)
422+
{
423+
if (projection.has_value())
424+
{
425+
DrawCircle(projection.value(), 20.0f, olc::RED);
426+
}
427+
}
376428
}
377429

378430
// Laser beam

olcUTIL_Geometry2D.h

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
| closest | closest | | | | |
165165
| overlaps | overlaps | overlaps | overlaps | overlaps | |
166166
| intersects | intersects | intersects | intersects | intersects | |
167-
| project | project | | project | | |
167+
| project | project | project | project | project | |
168168
---------+--------------+--------------+--------------+--------------+--------------+--------------+
169169
TRIANGLE | contains | contains | contains | contains | contains | |
170170
| closest | | | | | |
@@ -2184,8 +2184,35 @@ namespace olc::utils::geom2d
21842184
template<typename T1, typename T2, typename T3>
21852185
inline std::optional<olc::v_2d<T2>> project(const circle<T1>& c, const triangle<T2>& t, const ray<T3>& q)
21862186
{
2187-
// TODO:
2188-
return std::nullopt;
2187+
const auto s1 = project(c, t.side(0), q);
2188+
const auto s2 = project(c, t.side(1), q);
2189+
const auto s3 = project(c, t.side(2), q);
2190+
2191+
std::vector<olc::v_2d<T2>> vAllIntersections;
2192+
if (s1.has_value()) vAllIntersections.push_back(s1.value());
2193+
if (s2.has_value()) vAllIntersections.push_back(s2.value());
2194+
if (s3.has_value()) vAllIntersections.push_back(s3.value());
2195+
2196+
if (vAllIntersections.size() == 0)
2197+
{
2198+
// No intersections at all, so
2199+
return std::nullopt;
2200+
}
2201+
2202+
// Find closest
2203+
double dClosest = std::numeric_limits<double>::max();
2204+
olc::v_2d<T2> vClosest;
2205+
for (const auto& vContact : vAllIntersections)
2206+
{
2207+
double dDistance = (vContact - q.origin).mag2();
2208+
if (dDistance < dClosest)
2209+
{
2210+
dClosest = dDistance;
2211+
vClosest = vContact;
2212+
}
2213+
}
2214+
2215+
return vClosest;
21892216
}
21902217

21912218

@@ -2457,10 +2484,11 @@ namespace olc::utils::geom2d
24572484
if (s2 < 0)
24582485
return { q.origin + q.direction * s1 };
24592486

2460-
return { q.origin + q.direction * std::min(s1, s2) };
2487+
const auto& [min_dist, max_dist] = std::minmax(s1, s2);
2488+
return { q.origin + q.direction * min_dist, q.origin + q.direction * max_dist };
24612489
}
24622490
}
2463-
2491+
24642492
// intersects(q,r)
24652493
// Get intersection points where a ray intersects a rectangle
24662494
template<typename T1, typename T2>

0 commit comments

Comments
 (0)