@@ -277,43 +277,60 @@ namespace olc::utils::geom2d
277277
278278 // Returns closest point to point
279279 template <typename T1 , typename T2 >
280- inline olc::v2d_generic<T2 > closest (const olc::v2d_generic<T1 >& p1, const olc::v2d_generic<T2 >& p2)
280+ inline olc::v2d_generic<T1 > closest (const olc::v2d_generic<T1 >& p1, const olc::v2d_generic<T2 >& p2)
281281 {
282282 return p1;
283283 }
284284
285285 // Returns closest point on line to point
286286 template <typename T1 , typename T2 >
287- inline olc::v2d_generic<T2 > closest (const line<T1 >& l, const olc::v2d_generic<T2 >& p)
287+ inline olc::v2d_generic<T1 > closest (const line<T1 >& l, const olc::v2d_generic<T2 >& p)
288288 {
289289 auto d = l.vector ();
290- double u = std::clamp (double (d.dot (p - l.start ) / d.mag2 () ), 0.0 , 1.0 );
291- return l.start + d * u ;
290+ double u = std::clamp (double (d.dot (p - l.start )) / d.mag2 (), 0.0 , 1.0 );
291+ return l.start + u * d ;
292292 }
293293
294294 // Returns closest point on circle to point
295295 template <typename T1 , typename T2 >
296- inline olc::v2d_generic<T2 > closest (const circle<T1 >& c, const olc::v2d_generic<T2 >& p)
296+ inline olc::v2d_generic<T1 > closest (const circle<T1 >& c, const olc::v2d_generic<T2 >& p)
297297 {
298- return c.pos + (p - c.pos ).norm () * c.radius ;
298+ return c.pos + olc::vd2d (p - c.pos ).norm () * c.radius ;
299299 }
300300
301301 // Returns closest point on rectangle to point
302302 template <typename T1 , typename T2 >
303- inline olc::v2d_generic<T2 > closest (const rect<T1 >& r, const olc::v2d_generic<T2 >& p)
303+ inline olc::v2d_generic<T1 > closest (const rect<T1 >& r, const olc::v2d_generic<T2 >& p)
304304 {
305305 // This could be a "constrain" function hmmmm
306306 // TODO: Not quite what i wanted, should restrain to boundary
307- return olc::v2d_generic<T2 >{ std::clamp (p.x , r.pos .x , r.pos .x + r.size .x ), std::clamp (p.y , r.pos .y , r.pos .y + r.size .y ) };
307+ return olc::v2d_generic<T1 >{ std::clamp (p.x , r.pos .x , r.pos .x + r.size .x ), std::clamp (p.y , r.pos .y , r.pos .y + r.size .y ) };
308308
309309 }
310310
311311 // Returns closest point on triangle to point
312312 template <typename T1 , typename T2 >
313- inline olc::v2d_generic<T2 > closest (const triangle<T1 >& t, const olc::v2d_generic<T2 >& p)
313+ inline olc::v2d_generic<T1 > closest (const triangle<T1 >& t, const olc::v2d_generic<T2 >& p)
314314 {
315- // TODO:
316- return olc::v2d_generic<T2 >();
315+ olc::utils::geom2d::line<T1 > l{t.pos [0 ], t.pos [1 ]};
316+ auto p0 = closest (l, p);
317+ auto d0 = (p0 - p).mag2 ();
318+
319+ l.end = t.pos [2 ];
320+ auto p1 = closest (l, p);
321+ auto d1 = (p1 - p).mag2 ();
322+
323+ l.start = t.pos [1 ];
324+ auto p2 = closest (l, p);
325+ auto d2 = (p2 - p).mag2 ();
326+
327+ if ((d0 <= d1) && (d0 <= d2)) {
328+ return p0;
329+ } else if ((d1 <= d0) && (d1 <= d2)) {
330+ return p1;
331+ } else {
332+ return p2;
333+ }
317334 }
318335
319336
0 commit comments