Boolean function for intersection between circular segment and circle

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Boolean function for intersection between circular segment and circle

Post by Ref »

Talk about beating a dead horse.
Attachments
scanCircles.love
A lot of nothing.
(5.76 KiB) Downloaded 218 times
User avatar
BrotSagtMist
Party member
Posts: 659
Joined: Fri Aug 06, 2021 10:30 pm

Re: Boolean function for intersection between circular segment and circle

Post 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.
obey
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Boolean function for intersection between circular segment and circle

Post by Ref »

Don't know what kind of monster I've created but really doesn't have much to do with the original request.
Attachments
pointPusher.love
More nonsense
(5.82 KiB) Downloaded 223 times
nameless tee
Prole
Posts: 15
Joined: Mon Apr 22, 2019 8:16 am

Re: Boolean function for intersection between circular segment and circle

Post 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.
Attachments
intersect.love
(606 Bytes) Downloaded 240 times
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Boolean function for intersection between circular segment and circle

Post 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
User avatar
pgimeno
Party member
Posts: 3673
Joined: Sun Oct 18, 2015 2:58 pm

Re: Boolean function for intersection between circular segment and circle

Post 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 11600 times
Nice use of atan2 to find the collision angle. That's pretty creative.
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Boolean function for intersection between circular segment and circle

Post by Ref »

Uncle!
I give up.
What's going on bright eyes.
Any help appreciated.
User avatar
pgimeno
Party member
Posts: 3673
Joined: Sun Oct 18, 2015 2:58 pm

Re: Boolean function for intersection between circular segment and circle

Post 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
User avatar
darkfrei
Party member
Posts: 1204
Joined: Sat Feb 08, 2020 11:09 pm

Re: Boolean function for intersection between circular segment and circle

Post 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:
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
pgimeno
Party member
Posts: 3673
Joined: Sun Oct 18, 2015 2:58 pm

Re: Boolean function for intersection between circular segment and circle

Post by pgimeno »

edit: nvm, too off-topic
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest