From 07fbbe6247fb75f996c82d6b8897c80d09e11795 Mon Sep 17 00:00:00 2001 From: Max Cahill <1bardesign@gmail.com> Date: Tue, 14 Mar 2023 13:04:00 +1100 Subject: [PATCH 1/5] fixed issue with line routines on certain inputs --- intersect.lua | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/intersect.lua b/intersect.lua index 9bf955b..9e78f31 100644 --- a/intersect.lua +++ b/intersect.lua @@ -91,10 +91,10 @@ function intersect.nearest_point_on_line(a_start, a_end, b_pos, into) local point_to_start = b_pos:pooled_copy() :vector_sub_inplace(a_start) local factor = mathx.clamp01(point_to_start:dot(segment) / lensq) - point_to_start:release() into:set(segment) :scalar_mul_inplace(factor) :vector_add_inplace(a_start) + point_to_start:release() end segment:release() return into @@ -137,8 +137,10 @@ end --collide a line segment with a circle function intersect.line_circle_collide(a_start, a_end, a_rad, b_pos, b_rad, into) - into = intersect._line_to_point(a_start, a_end, b_pos, into) - return intersect._line_displacement_to_sep(a_start, a_end, into, a_rad + b_rad) + local nearest = intersect.nearest_point_on_line(a_start, a_end, b_pos, vec2:pooled()) + into = intersect.circle_circle_collide(nearest, a_rad, b_pos, b_rad, into) + nearest:release() + return into end --collide 2 line segments @@ -165,6 +167,8 @@ function intersect.line_line_collide(a_start, a_end, a_rad, b_start, b_end, b_ra elseif b_degen then --b is just circle return intersect.line_circle_collide(a_start, a_end, a_rad, b_start, b_rad, into) + else + error("should be unreachable") end end --otherwise we're _actually_ 2 line segs :) @@ -188,14 +192,14 @@ function intersect.line_line_collide(a_start, a_end, a_rad, b_start, b_end, b_ra --check coincident lines local intersected if - math.abs(numera) < COLLIDE_EPS and - math.abs(numerb) < COLLIDE_EPS and - math.abs(denom) < COLLIDE_EPS + math.abs(numera) == 0 and + math.abs(numerb) == 0 and + math.abs(denom) == 0 then intersected = "both" else --check parallel, non-coincident lines - if math.abs(denom) < COLLIDE_EPS then + if math.abs(denom) == 0 then intersected = "none" else --get interpolants along segments @@ -215,7 +219,7 @@ function intersect.line_line_collide(a_start, a_end, a_rad, b_start, b_end, b_ra end end end - assert(intersected) + assert:some(intersected) if intersected == "both" then --simply displace along A normal @@ -229,7 +233,7 @@ function intersect.line_line_collide(a_start, a_end, a_rad, b_start, b_end, b_ra vec2.release(a_dir, b_dir) - --dumb as a rock check-corners approach + --dumb as a rocks check-corners approach --todo: pool storage --todo proper calculus from http://geomalgorithms.com/a07-_distance.html local search_tab = {} From ff2ab5f1aa89f0955d8e7df08c2798b1864c79a6 Mon Sep 17 00:00:00 2001 From: Max Cahill <1bardesign@gmail.com> Date: Thu, 16 Mar 2023 12:14:51 +1100 Subject: [PATCH 2/5] fixed intersect relying on assert being exported --- intersect.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intersect.lua b/intersect.lua index 9e78f31..057fc44 100644 --- a/intersect.lua +++ b/intersect.lua @@ -219,7 +219,7 @@ function intersect.line_line_collide(a_start, a_end, a_rad, b_start, b_end, b_ra end end end - assert:some(intersected) + assert(intersected) if intersected == "both" then --simply displace along A normal From 2c313362106fd522cf88f2e4da3fb63bf813ce07 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Sun, 19 Mar 2023 12:19:08 -0400 Subject: [PATCH 3/5] add assert.one_of --- assert.lua | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/assert.lua b/assert.lua index 8998452..2951633 100644 --- a/assert.lua +++ b/assert.lua @@ -10,7 +10,6 @@ can call nop() to dummy out everything for "release mode" (if you're worried about that sort of thing) ]] - local _assert = assert --proxy calls to global assert @@ -82,6 +81,20 @@ function assert:type_or_nil(a, t, msg, stack_level) return a end +--assert a value is one of those in a table of options +function assert:one_of(a, t, msg, stack_level) + local pass = false + for index = 1, #t do + if t[index] == a then + pass = true + break + end + end + + assert:equal(pass, true, msg, stack_level) + return a +end + --replace everything in assert with nop functions that just return their second argument, for near-zero overhead on release function assert:nop() local nop = function(_, a) From c2316e2ad82219f1db50c4f7e5abe7cf461c8625 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Sun, 19 Mar 2023 12:19:57 -0400 Subject: [PATCH 4/5] don't remove this whitespace --- assert.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/assert.lua b/assert.lua index 2951633..9d6f95c 100644 --- a/assert.lua +++ b/assert.lua @@ -10,6 +10,7 @@ can call nop() to dummy out everything for "release mode" (if you're worried about that sort of thing) ]] + local _assert = assert --proxy calls to global assert From 4cbbf6c068ef01af09086745992f3806799dcce7 Mon Sep 17 00:00:00 2001 From: TurtleP Date: Mon, 20 Mar 2023 09:48:56 -0400 Subject: [PATCH 5/5] address pr comment --- assert.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/assert.lua b/assert.lua index 9d6f95c..8cfccb0 100644 --- a/assert.lua +++ b/assert.lua @@ -84,16 +84,17 @@ end --assert a value is one of those in a table of options function assert:one_of(a, t, msg, stack_level) - local pass = false - for index = 1, #t do - if t[index] == a then - pass = true - break + for _, value in ipairs(t) do + if value == a then + return a end end - assert:equal(pass, true, msg, stack_level) - return a + error(("assertion failed: %s not one of %s %s"):format( + tostring(a), + table.concat(t, ", "), + _extra(msg) + ), 2 + (stack_level or 0)) end --replace everything in assert with nop functions that just return their second argument, for near-zero overhead on release