## As: Circle To Line Hit Testing

• 5,951 Views
• 33 Replies
Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
As: Circle To Line Hit Testing 2005-12-17 09:23:03

AS: Main

Requires base math.

Well, here you will detect if a line is hitting a circle or not. This is done in the

following way:

1)finding the center of the circle
3)calculating the line's equation
4)finding the distance between the line and the center
5)comparing the distance between the line and the circle's center with the circle's radius

Step 1
This is obviously the easiest part by far. The center of a circle is always it's width

devided by two and it's height devided by two. so assuming your circle is a movieclip (which

it should be) all you have to do is type
var cx:Number=(this._x+(this._width+this._x)) /2;
var cy:Number=(this._y+ (this._y+this._height) /2;

Step 2
Finding the radius of a circle is not much harder, the radius is just the diameter devided

by two, and the diameter is the width or the height of the circle (since they are

identical).

Step 3
Finding the line's equation. Now in case you don't have the line's equation you can simply

calculate it. calculating line eqations is explained in detail in this thread

a line is ususally in the y=mx+n or the ax+by+c=0 format, I like the first type better

You know a line's increasment is the reduction of it's y devided by it's x reduction, you

can just directly use _width and _height for that
the following is in the line's movieclip

var m:Number=_width/_height;

now to calculate the offset (n value) use one point you know the line has, it's _x and _y.
now y=mx+n so 0=mx+n-y so -n=mx-y so n=y-mx

var n:Number=y - (m*_x);

this is your offset and you have your line's equation since you know M and N.

Step 4

Here comes the harder part, you need to calculate the distance between the center x and

center y and the line.

the formula for doing so is |ax+by+c| / sqrt(a^2+b^2) . where a and b and c can be found

using the line's equation and x and y are the point's values.

let's do this with coding, first of all we need to convert our mx+n=y into a ax+by+c=0, now,

we can just do so by moving y to the other end creating -1*y + m*x + n = 0, our a is equal

to m and our b is equal to -1, our c is equal to n.
var a:Number=lineMC.m;
var b:Number=-1;
var c:Number =lineMC.n;
var x:Number=circleMC.cx;
var y:Number=circleMC.cy;
var distance:Number= Math.abs(a*x + b*y + c) / Math.sqrt(a*a + b*b);

Importent note, THIS CAN BE USED IN 3D to find the distance between a plane and a point or a

vector and a point using |ax+by+cz+d| / Math.sqrt(a*a+b*b+c*c);

now you have the distance between the line and the point

Step 5

Now we compare the distance to the radius. this is based on the fact the radius is the

distance from the center point to every single point on the circle. if the distance is

smaller than the radius the line "enters" the circle. if it is equal to the radius it

touches it in exactly one point (and the angle between it and the line from the point it

touches and the center is 90 degrees) and if the radius is bigger the line and the circle do

not touch eachother.

//does not hit
}else{
//does hit
}

take note this can be calculated in another way, you can find the circle's equation and

compare it to the line's, but you'll just end up doing the same thing eventually.

Feel free to ask any questions.

Inglor out.

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 09:24:34

my AS: Main link fucked up :/ anyhow here it is

AS: Main beacuse we all <3 denvish

DannyIsOnFire
DannyIsOnFire
• Member since: Apr. 14, 2005
• Offline.
Forum Stats
Member
Level 21
Movie Buff
Response to As: Circle To Line Hit Testing 2005-12-17 09:25:40

Another great AS topic by the mighty inglor
Havent seen you around in a while so its good to see you back and posting again :)

Rantzien
Rantzien
• Member since: Jan. 27, 2005
• Offline.
Forum Stats
Member
Level 15
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 09:44:59

Cool, definitely a long time since your last thread. I've got a couple of comments, a bit picky but still =)

Step 1
This is obviously the easiest part by far. The center of a circle is always it's width devided by two and it's height devided by two. so assuming your circle is a movieclip (which it should be) all you have to do is type
var cx:Number=(this._x+(this._width+this._x)) /2;
var cy:Number=(this._y+ (this._y+this._height) /2;

Here you are assuming that the registration point is in the upper left, nothing wrong with that but it should be mentioned =)

Step 2
Finding the radius of a circle is not much harder, the radius is just the diameter devided by two, and the diameter is the width or the height of the circle (since they are identical).

Could have been step 1, to be really picky.

Step 3
Finding the line's equation. Now in case you don't have the line's equation you can simply calculate it. calculating line eqations is explained in detail in this thread
a line is ususally in the y=mx+n or the ax+by+c=0 format, I like the first type better

You know a line's increasment is the reduction of it's y devided by it's x reduction, you can just directly use _width and _height for that
the following is in the line's movieclip
var m:Number=_width/_height;

Never thought of that way to do it, smart =)

Good tutorial overall, can be used in for example shooting games, instead of, silly thought, hitTesting the bullet =)

Actually, you should post a sample. Good job

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 09:59:40

At 12/17/05 09:44 AM, Santazien wrote: Here you are assuming that the registration point is in the upper left, nothing wrong with that but it should be mentioned =)

this is actually quite an importent comment, thanks.

Rantzien
Rantzien
• Member since: Jan. 27, 2005
• Offline.
Forum Stats
Member
Level 15
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 10:45:18

At 12/17/05 09:59 AM, Inglor wrote: this is actually quite an importent comment, thanks.

You're welcome =)

Arab
Arab
• Member since: Dec. 4, 2004
• Offline.
Forum Stats
Member
Level 19
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 11:22:27

At 12/17/05 09:24 AM, Inglor wrote: AS: Main beacuse we all <3 denvish

No arguing with that, <3

Great thread, I can't believe I didnt think of how to do this earlier.

liam
liam
• Member since: Dec. 11, 2004
• Offline.
Forum Stats
Member
Level 22
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 11:47:20

An example por favor.

It looks cool, can't read now though because of f00d.

Sup, bitches :)

Drake-SI
Drake-SI
• Member since: Mar. 7, 2005
• Offline.
Forum Stats
Member
Level 21
Programmer
Response to As: Circle To Line Hit Testing 2005-12-17 12:19:56

Divided, not devided. Other than that, good job, as usual

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 12:31:56

At 12/17/05 12:19 PM, Drake_SI wrote: Divided, not devided. Other than that, good job, as usual

right. we have a tredition here where I work, so if my post have abnormal spelling, weird pictures or unrelated text it's probably me, but this time it was not :P

Glaiel-Gamer
Glaiel-Gamer
• Member since: Dec. 28, 2004
• Offline.
Forum Stats
Member
Level 28
Game Developer
Response to As: Circle To Line Hit Testing 2005-12-17 13:03:00

can we have a techinical example of this (like my line-line one)? Thanks. It's cool

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2005-12-17 14:12:52

ive been trying to think of a way to do this for a while.
great job

dELtaluca
dELtaluca
• Member since: Apr. 16, 2004
• Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 14:16:55

the only thing you didnt do, is allow for vertical lines

if the line is vertical, then the gradient will be infinity or negative infinity and youll start getting NaN's with rest of code

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2005-12-17 14:26:24

ok that last post was just after i read the title and made sure there was no for loops. now that i've read it i cant believe i did figure this out!!! its so simple!!!thanks so much. the thing is, when i read these i never look at the codes, just descriptions so that i dont uninintentionally steal your code. well you explained it beautifully.

the only thing i dont like is the center equation. what if the circle is an enemy, with rotating AI and stuff. you wouldnt want the registration point in a corner. the best thing would be to just have it centered. but of course if you dont want it there or the corner that you would have to get the midpoints of the accuall bounds using getBounds.

other than that its great!

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2005-12-17 14:27:54

At 12/17/05 02:26 PM, ImpotentBoy2 wrote: i cant believe i did figure this out

meant to say didn't

sorry to double post but that typo makes me sound like a dick.

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 14:32:06

it won't work for vertical lines

I presume people know they should check if deviding by zero when deviding. I also presume that hitTesting a circle against a x value is something we can all do since it's linear.

At 12/17/05 02:26 PM, ImpotentBoy2 wrote: its great!

thanks a lot/

Begoner
Begoner
• Member since: Oct. 10, 2004
• Offline.
Forum Stats
Member
Level 10
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 14:33:34

At 12/17/05 02:16 PM, -dELta- wrote: the only thing you didnt do, is allow for vertical lines

if the line is vertical, then the gradient will be infinity or negative infinity and youll start getting NaN's with rest of code

Yeah, with a vertical line, the _width is 0, and dividing by 0 will mess everything up. It's better to use the standard form ( ax + by = c ) of representing a line rather than slope-intercept form, which is just a slight change from your code. You can easily convert slope-intercept form to standard form to get rid of /0s. Other than that, great tutorial.

dELtaluca
dELtaluca
• Member since: Apr. 16, 2004
• Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to As: Circle To Line Hit Testing 2005-12-17 15:36:26

At 12/17/05 02:33 PM, Begoner wrote:
At 12/17/05 02:16 PM, -dELta- wrote: the only thing you didnt do, is allow for vertical lines

if the line is vertical, then the gradient will be infinity or negative infinity and youll start getting NaN's with rest of code
Yeah, with a vertical line, the _width is 0, and dividing by 0 will mess everything up. It's better to use the standard form ( ax + by = c ) of representing a line rather than slope-intercept form, which is just a slight change from your code. You can easily convert slope-intercept form to standard form to get rid of /0s. Other than that, great tutorial.

that or you can just have a special case for vertical lines

find the gradient, if the gradient is inf, or -inf, then do whatever, else to normal code

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2006-01-11 21:19:02

i found another way to do this. and i thinks its easier. since the two line always form a 90 degree angle, we can use triginometry.
sin(r)=o/h
r being the angle, o is the side opposite to the angle and h is the hypotenuse. we need to find o, h and r are given(or at least can be found out)
so we arrange it to say
o= h*sin(r)
and we come up with

r=Math.atan2(y2-y1, x2-x1);
// angle of line
r2 = Math.atan2(yC-y1, xC-x1);
// angle of axis
d = Math.sqrt(((x1-xC)*(x1-xC))+((y1-yC)*(y1-y
C)));
//hypotenuse
o = d*Math.sin(Math.abs(r-r2));
// opposide side

pictures are fun

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2006-01-11 21:20:51

oops on the picture i labeled them wrong, switch d1 and d2. the formulas right though

Rammer
Rammer
• Member since: Jun. 8, 2003
• Offline.
Forum Stats
Member
Level 33
Programmer
Response to As: Circle To Line Hit Testing 2006-01-11 22:49:20

At 12/17/05 12:31 PM, Inglor wrote:
At 12/17/05 12:19 PM, Drake_SI wrote: Divided, not devided. Other than that, good job, as usual
right. we have a tredition here where I work, so if my post have abnormal spelling, weird pictures or unrelated text it's probably me, but this time it was not :P

:S *cough*.

snyggys

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2006-01-12 01:04:45

At 1/11/06 09:19 PM, ImpotentBoy2 wrote: i found another way to do this.

just thought id show an example of my way
:D

attention Whore

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2006-01-12 14:40:21

not a bad way, I doubt it is easier though. I can prove your way using mine =P

GeoKureli
GeoKureli
• Member since: Apr. 1, 2003
• Offline.
Forum Stats
Supporter
Level 20
Game Developer
Response to As: Circle To Line Hit Testing 2006-01-12 14:53:56

At 1/12/06 02:40 PM, Inglor wrote: not a bad way, I doubt it is easier though. I can prove your way using mine =P

i find it easier, i dont mean its better though, they both have the same flaws too. like how they lack a single direction. for instance without added code they both will say they intersect if aim in the opposite direction of it.

dELtaluca
dELtaluca
• Member since: Apr. 16, 2004
• Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to As: Circle To Line Hit Testing 2006-01-18 16:15:55

the problem with both your methods is your using sqrt's or trig, i can do it using only multiplication, division, addition and subtraction

Rustygames
Rustygames
• Member since: May. 7, 2005
• Offline.
Forum Stats
Supporter
Level 19
Programmer
Response to As: Circle To Line Hit Testing 2006-01-18 16:18:27

At 1/18/06 04:15 PM, -dELta- wrote: the problem with both your methods is your using sqrt's or trig, i can do it using only multiplication, division, addition and subtraction

Damn what I have I done

noooooooooooooooo!!!!!!!!!!!!!!!

Heh Delta has impressed me so much today that I think noone else will ever impress me again.

Rantzien
Rantzien
• Member since: Jan. 27, 2005
• Offline.
Forum Stats
Member
Level 15
Blank Slate
Response to As: Circle To Line Hit Testing 2006-01-18 17:10:47

At 1/18/06 04:15 PM, -dELta- wrote: i can do it using only multiplication, division, addition and subtraction

Good job. Now do it using this apple. *Hands over lemon*

Inglor
Inglor
• Member since: Jan. 26, 2003
• Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to As: Circle To Line Hit Testing 2006-01-18 17:13:19

At 1/18/06 04:15 PM, -dELta- wrote: the problem with both your methods is your using sqrt's or trig, i can do it using only multiplication, division, addition and subtraction

my method doesn't use trig, and as for sqrt you can just multiply a number by itself and compare it to the other non-sqrted number, there, no trig or squares, geez, makes less logic though

dELtaluca
dELtaluca
• Member since: Apr. 16, 2004
• Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to As: Circle To Line Hit Testing 2006-01-18 17:14:35

At 1/18/06 05:13 PM, Inglor wrote: stiuff

i still prefer my method :p

Rustygames
Rustygames
• Member since: May. 7, 2005
• Offline.
Forum Stats
Supporter
Level 19
Programmer
Response to As: Circle To Line Hit Testing 2006-01-19 12:33:28

I have been reading through this and understood how to do it well. When I went to try it it turns out its completely wrong :P
Can someone perhaps correct the mistakes or redo the thread making it alot clearer on what is going on please.