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.
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
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.
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)
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:
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!
Last edited by ivan on Thu Feb 18, 2021 5:56 pm, edited 6 times in total.
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.
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:
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.
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...
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:
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.
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.
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.