Page 1 of 2

How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 2:28 am
by PenguinKing
Summary:
I'm looking to implement some sort of Attack Radius system in my game that I've started working on recently, however; I'm not really sure how to implement such a thing... I don't really have any code on what I'm trying to do, but I've thrown something together in order to make it easier for you guys to see what I'm trying to do.

Code Reference:
For context: 'self' refers to the specific instance of "Turret" that has been added to a 'listOfTurrents' table.

Code: Select all

function Turret:pointToObject(obj)
	local dist = math.sqrt((obj.x-self.x)^2, (obj.y-self.y)^2)
	
	if dist <= self.attackRadius then
		self.angle = math.atan2(self.y-obj.y,self.x-obj.x)
	end
end

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 2:52 am
by eliddell
I think you've got the idea: apply the Pythagorean Theorem to see if a given point is within the radius of your circle. If you want to do this for a square with a size larger than one pixel, you can do it by checking each corner of the square.

Protip: You don't actually need to perform the square root, which is a slow operation—just square self.attackRadius and compare the squares.

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 3:28 am
by PenguinKing
Hmm... I'm now sure I understand where you're coming from in terms of using pythag... I mean, I've used pythag quite a lot in the past, yet, this has been giving me a lot of trouble... Also, how would I check each corner of the square? (the square is going to be 8x8px)

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 7:53 am
by ivan
I think your example code is fine. Just check the distance from the turret to the center of the enemy, there is no need to involve squares/rectangles. If you insist then here is the code: https://2dengine.com/?p=intersections#C ... _rectangle

To determine if the square is *entirely* inside the circle you need to check:

Code: Select all

if the distance between the center of the square to the center of the circle
is less than the difference of the radius of the circle minus
the length of the diagonal from the center of the square to one of its corners
TLDR: find the length of the diagonal form the center of the square to one if its corners - then check the two shapes as if they are both circles


TLDRx2: The correct way is to add the radius of the circle to each side of the square, and that will reduce the problem to point vs square which is trivial. Then you can compare the distance from the center point of the circle to the edges of the expanded square against the circle's radius.

What pgimeno said!

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 8:56 am
by pgimeno
ivan wrote: Thu Feb 18, 2021 7:53 am TLDR: find the length of the diagonal form the center of the square to one if its corners - then check the two shapes as if they are both circles
That's not so precise as checking all four corners.

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 9:00 am
by PenguinKing
ivan wrote: Thu Feb 18, 2021 7:53 am I think your example code is fine. Just check the distance from the turret to the center of the enemy, there is no need to involve squares/rectangles. If you insist then here is the code: https://2dengine.com/?p=intersections#C ... _rectangle

To determine if the square is *entirely* inside the circle you need to check:

Code: Select all

if the distance between the center of the square to the center of the circle
is less than the difference of the radius of the circle minus
the length of the diagonal from the center of the square to one of its corners
TLDR: find the length of the diagonal form the center of the square to one if its corners - then check the two shapes as if they are both circles
Hey there, I've got the calculations and such working now, however; whenever the square moves or does anything like that, the distance doesn't update at all, I've print spammed and looked at the console and I've not been getting anything in terms of distance being changed for some reason... Here's the code I've got written up so far.

Code: Select all

function Turret:pointTowards(obj)
	local dx = obj.width/2
	local dy = obj.height/2
	local dist = math.sqrt((dx-self.x)^2+(dy-self.y)^2)
	
	if dist < self.attackRadius then
		print("This is working!")
	end
end
However; whenever the object comes into contact with, or is inside of the radius, the if statement doesn't run for some reason... Like I've said before, I've print spammed everything in the function and yes, I've even tried adding in the obj.x and obj.y to the equation but that only increasing the distance indefinitely...

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 12:12 pm
by pgimeno
ivan wrote: Thu Feb 18, 2021 7:53 am TLDR: find the length of the diagonal form the center of the square to one if its corners - then check the two shapes as if they are both circles
pgimeno wrote: Thu Feb 18, 2021 8:56 am That's not so precise as checking all four corners.
Here's an example where it reports an incorrect result:
Image
The square is completely contained within the outer circle, yet the algorithm reports otherwise because the circle that encloses the square is partially out of the outer circle.

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 2:07 pm
by darkfrei
Something like:
For corner in pairs corners do
If distance(corner, center) > radius then Return true -- at least one corner is out of circle

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 2:26 pm
by ivan
Good catch there pgimeno!
The correct way is to add the radius of the circle to each side of the square, and that will reduce the problem to point vs square which is trivial. Then you can compare the distance from the center point of the circle to the edges of the expanded square against the circle's radius.

Re: How would one check if a square is within a circle?

Posted: Thu Feb 18, 2021 5:20 pm
by pgimeno
darkfrei wrote: Thu Feb 18, 2021 2:07 pm Something like:
For corner in pairs corners do
If distance(corner, center) > radius then Return true -- at least one corner is out of circle
Yes, or equivalently:

If distance(corner, center)^2 > radius^2 then Return true -- at least one corner is out of circle

By cancelling the square root in distance() with the squaring above, you save four square roots. The radius^2 can be calculated once before the loop. I believe that's the protip that eliddell suggested.

ivan wrote: Thu Feb 18, 2021 2:26 pm Good catch there pgimeno!
The correct way is to add the radius of the circle to each side of the square, and that will reduce the problem to point vs square which is trivial. Then you can compare the distance from the center point of the circle to the edges of the expanded square against the circle's radius.
That wouldn't work either. The Minkowski difference of a square and a circle is not a square, it's a square with rounded borders, and checking if a point is inside that shape is costly.