Collision box / ball

So my question is very straight forward:
How do I check if something is within a circle?

I am talking 2D here.

I know how to check if something is withing a box/rectangle, that is not hard.

if item.x >= area.x and item.x <= area.x + area.width
and item.y >= area.y and item.y <= area.y + area.height then
  -- statement is true
end

But how check something similar for a ball? So to speak…

.@akaJag Try this example. You can change the size of the circle/ellipse with the parameters. Just slide your finger across the circle/ellipse. It will show “inside” when you finger is inside the circle/ellipse.


function setup()
    parameter.integer("a",1,400,200)
    parameter.integer("b",1,400,100)
end

function draw()
    background(40, 40, 50)
    
    xc=250    -- center of ellipse x axis
    yc=400    -- center of ellipse y axis
    
    fill(255)
    ellipse(xc,yc,a*2,b*2)    -- draw ellipse
    
    x=CurrentTouch.x    -- touched x value
    y=CurrentTouch.y    -- touched y value
    
    -- determine if touched value is inside ellipse
    fill(255,0,0)
    if (y-yc)^2/b^2+(x-xc)^2/a^2 <= 1 then 
        text("inside",xc,yc)        
    end    
end

Yea great that works fine!
But HOW the fuq does it work???

if (y-yc)^2/b^2+(x-xc)^2/a^2 <= 1 then

I cant understand what that does! Can you be so dear and explain it!?

a = horisantal radius
b = verticsl radius

I get that part, but why do you raise it to the power of 2? (^2)
To say it in a simple way: I don’t get that equation.

Google it, I’m sure there’s an explanation out there, this is a very common request in graphics programming

To make things easy, think of a circle. If you touch outside the circle, then the calculation will have a value greater than 1. If you touch exactly on the edge of the circle it will calculate a value of 1. If you touch inside the circle it will calculate a value less than 1. Basically its using the formula for an ellipse, rearranged to use the coordinates for the center of the ellipse, and the coordinates of where your finger is touching the screen, to tell if your touching inside or outside the ellipse edge. Not sure if that helps.

@Ignatz Wich keywords shall I use? I have no clue on what to search fot.
@dave1707 It kinda helps… The most non-understanding thing about it is the math behind that formula, wich I am interested in and want to learn!

perhaps a simpler approach that you will understand is to calculate the distance from your touch to the centre of the circle, and if it is less than the radius, you are inside the circle.

Something like this

if vec2(touch.x,touch.y):dist(vec2(circle.x,circle.y)) <=radius then --inside circle

That sounds a lot simpler, but what does that vec2() and dist() do?
(Sorry I’m a newbie at this)

I could explain, but what you really need to do is read up on the Lua programming language, and look at the Codea documentation, which explains these functions (it’s a big page, so just search on it)

https://bitbucket.org/TwoLivesLeft/core/wiki/Documentation

We all start by feeling confused, don’t worry #-o

You see this in the wrong way Ignatz, I know Lua, I have known it for a long while. But I am brand new to Codea.
Codea opens doors I have never seen, 3D graphics, proper physics, sound, images, anything!
Now what does those vec2() stuff do? (I will read the documentation anyways :slight_smile: )

sorry, I thought Lua had vec2, I kind of learned everything at the same time and didn’t notice where it all came from.

Vec2 is just a table with two items, so vec2(a,b) is equivalent to {x=a,y=b} in Lua.

it’s good for 2D graphics, and Codea provides a number of functions for it. The documentation should help you with that.

If you know Lua, you should really enjoy Codea. Also have a look at the tutorials on the wiki. I have about 25 just on 3D graphics alone.

A vector is a list of numbers. In Codea, a vec2 is a vector of length 2, whence a list of two numbers. Such a vector can be used to represent a point on the screen by using the first number to measure how far across and the second number how far up. Thus we can use vec2s to represent points on the screen.

The next concept that is needed is that of distance. There are lots of ways to define a distance function, but the most common is the Euclidean distance. If we take two points, say p and q, then we want to measure the distance between them. Outside a program we would simply stick a ruler between them. Inside a program we need some way to compute it. Since each of these points can be represented by a vector (of length 2), we can take these two vectors and use some formula to compute the distance between them. That formula is the Euclidean distance function. If the first vector has components x1 and y1 and the second has components x2 and y2 then the Euclidean distance between p and q is given by the formula:

sqrt( (x1 - x2)^2 + (y1 - y2)^2 )

where a^2 denotes the square of a.

This is just a formula. What makes it the right formula is Pythagoras’ theorem.

Now we need the concept of a circle. A circle centred on a point p of radius r is defined to be the set of points which are exactly distance r from p. That is, it consists of all of those points q with the property that d(p,q) = r. From the formula, this means that q is on the circle if and only if

sqrt( (x1 - x2)^2 + (y1 - y2)^2 ) = r

Now a circle divides the plane into two regions: an inside and an outside. These are characterised as follows: the inside consists of all of those points of distance to p strictly less than r and the outside of those points of distance strictly greater than r. (The fact that the division is clean is due to something called the Intermediate Value Theorem.) So to test “Is q inside the circle?” programmatically we ask “Is the distance from p to q less than r?” (If we say “inside or on the circle” we ask “less than or equal to”; in practice the distinction is ignorable.)

So we might write:

if  math.sqrt( (x1 - x2)^2 + (y1 - y2)^2 ) < r then

(using math.sqrt as that is the name for the square root function in Codea)

However, square roots are expensive to compute so we use a trick to simplify this. The trick is that if a and b are positive numbers then a < b if and only if a^2 < b^2. Thus the above test is equivalent to the following (ie is true if and only if the following is true):

if (x1 - x2)^2 + (y1 - y2)^2 < r^2 then

and that’s almost the formula that @dave1707 has. There are two small differences. The first is that dave’s formula is for an ellipse, which is a distorted circle. The second is that his would be if (x1 - x2)^2/r^2 + (y1 - y2)^2/r^2 < 1 then. This is equivalent, since it uses the fact that if c is positive then a < b if and only if a/c < b/c. I’m not sure which is the more efficient.

Math, I’m telling ya, is sometimes confusing

Thank you very much for that great explination btw!!

Im having the same issue with my code, and it doesnt want to make a new physics.body when two bodies collide, it freezes and closes out of the app. Any ideas?

@tylsamonster- you may need to post some code so we can see the problem.

A common problem with physics objects is not deleting them fully so they hang around as unseen zombies. If you have (say) defined p=physics.body(…), then you need to do this to delete it
p:destroy()
p=nil
Ie a two step process

@Ignatz he has his own discussion, it’s under… “Help creating a game”