Page 3 of 4

Re: Boolean function for intersection between circular segment and circle

Posted: Mon Aug 09, 2021 4:01 pm
by Ref
Talk about beating a dead horse.

Re: Boolean function for intersection between circular segment and circle

Posted: Mon Aug 09, 2021 4:27 pm
by BrotSagtMist
Thats actually quite hypnotic.
But whats the logic behind the explosion getting scaled with the target? Ammo savings?

This would look super cool if the balls would get pushed by a hit.

Re: Boolean function for intersection between circular segment and circle

Posted: Mon Aug 09, 2021 8:50 pm
by Ref
Don't know what kind of monster I've created but really doesn't have much to do with the original request.

Re: Boolean function for intersection between circular segment and circle

Posted: Tue Aug 10, 2021 11:57 am
by nameless tee
I tried to simplify the handling of the corner cases while avoiding dealing with angles as much as possible.

Code: Select all

local abs, sin, cos, sqrt, min, max = math.abs, math.sin, math.cos, math.sqrt, math.min, math.max
function intersect(cx, cy, cr, sx, sy, sr, a1, a2)
	cx, cy = (cx - sx) / sr, (cy - sy) / sr
	local a = (a1 + a2) * .5
	local ar, ai = cos(a), sin(a)
	cx, cy = cx * ar + cy * ai, abs(cy * ar - cx * ai)
	a = abs(a - a1)
	ar, ai = cos(a), sin(a)
	cx, cy = ar * cx + ai * cy, ar * cy - ai * cx
	if cy <= 0 then
		return max(cy, sqrt(cx * cx + cy * cy) - 1) * sr - cr < 0
	else
		cx = cx - max(min(cx, 1), 0)
		return sqrt(cx * cx + cy * cy) * sr - cr < 0
	end
end
Edit: Forgot to use some of the cached math.* functions. Didn't correct that in the .love, though.

Edit 2: Maybe the two square roots can be eliminated (the last one at least). They are there because I started by writing a signed distance function. Maybe the divisions at the top can be made into some multiplications further down.

Re: Boolean function for intersection between circular segment and circle

Posted: Tue Aug 10, 2021 3:08 pm
by Ref
As far as I can tell, we are all beating the same dead horse.
Haven't found any edge cases but am sure eagle eyes will find some.

Code: Select all

--[[
format:
	circle:	c = { x, y, r }
	arc: 		a = { x, y, a1, a2, l }
				a.a = ( a.a2 + a.a1 ) / 2			-- arc center angle
				a.w = abs( a.a2 - a.a1 ) / 2		-- arc half width
]]
contactArcCircle = function( a, c )				-- arc, circle
	local dis	= sqrt( (a.x-c.x)^2 + (a.y-c.y)^2 )	-- center distance: arc => circle
	if dis <= c.r then return true end			-- arc center is in or touching circle
	local angCE	= atan2( c.r, dis )			-- angle: circle center to circle edge
	local angCA	= atan2( a.y-c.y, a.x-c.x )+pi	-- angle: circle center to arc center
	return (angCA+angCE)>a.a-a.w and (angCA-angCE)<a.a+a.w and dis<=(a.l+c.r)
	end

Re: Boolean function for intersection between circular segment and circle

Posted: Tue Aug 10, 2021 5:21 pm
by pgimeno
Nice job @ nameless tee! Yes I see how to get rid of the second square root. It's also easy to get rid of two subtractions, using ... < cr instead of ... - cr < 0. Due to the lack of comments I can't evaluate your approach. The use of ar and ai sounds like it is based on complex math.

@ Ref, pointing right is still a problem, as is in your demos above (just open the arc to about 120° or more, and pay attention to the collisions above and below the centre of the screen as it sweeps the right side of the screen, when they are touched simultaneously by the rotating sector). And you got rid of the area that I marked in blue near the arc centre, but not of the others, so a collision is detected in this case:
incorrect-collision.png
incorrect-collision.png (3.05 KiB) Viewed 11448 times
Nice use of atan2 to find the collision angle. That's pretty creative.

Re: Boolean function for intersection between circular segment and circle

Posted: Tue Aug 10, 2021 8:47 pm
by Ref
Uncle!
I give up.
What's going on bright eyes.
Any help appreciated.

Re: Boolean function for intersection between circular segment and circle

Posted: Wed Aug 11, 2021 8:52 am
by pgimeno
Angles are hard to compare. There's always that corner case that you forgot to take into account. That's one reason why vector math is preferable when possible, because it doesn't depend on quadrants and does not have wraparound.

Here's a function to determine if an angle is between two other angles, but I'm not sure it will help in this case. The idea is to reduce the used angles to [0, 2pi) and use a1 as base, making the other angles relative to it.

Code: Select all

local pi2 = 2 * math.pi

local function angleBetween(a, a1, a2)
  a = (a - a1) % pi2
  a2 = (a2 - a1) % pi2
  return a <= a2
end

Re: Boolean function for intersection between circular segment and circle

Posted: Wed Aug 11, 2021 9:02 am
by darkfrei
pgimeno wrote: Wed Aug 11, 2021 8:52 am

Code: Select all

local pi2 = 2 * math.pi
Tau, 2*pi is a tau:

Re: Boolean function for intersection between circular segment and circle

Posted: Wed Aug 11, 2021 5:49 pm
by pgimeno
edit: nvm, too off-topic