File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Circle collision Detection: Solved =) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Circle collision Detection: Solved =)" Watch "Circle collision Detection: Solved =)" New topic
Author

Circle collision Detection: Solved =)

Mark Quin
Greenhorn

Joined: Oct 21, 2007
Posts: 15
I have 2 moving circles and I am trying to detect if they hit each other. I want to use some type of simple collision detection to find when they touch.

So far I have:
Circle 1 size = (20,20)
Circle 2 size = (30,30)
ax,ay = the x,y position of circle 1
bx,by = the x,y position of circle 2
dx=(ax-bx)^2
dy=(ay-by)^2

This one did not seem to work right at all.


This works some what, but not for all sides of the circle. Some spots the circles were not touching but it said that were.

How can I get it to check to see if the circles hit?
Also, if you know of any examples that work I would like to look at them. I have been trying all kinds of things. I have been trying for hours to get this to work right.

[ October 21, 2007: Message edited by: Mark Quin ]

[ October 22, 2007: Message edited by: Mark Quin ]
[ October 23, 2007: Message edited by: Mark Quin ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
In your last formula, where does the number 26 come from?
[ October 21, 2007: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

For any two circles, they touch if the distance between the two centers is equal to the sum of the two radiuses, and overlap if the distance is larger.

So if you make dx the radius of the first circle, and dy the radius of the second, then your first piece of code should work if you change the < symbol to >.
[ October 22, 2007: Message edited by: Rob Prime ]

SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
bart zagers
Ranch Hand

Joined: Feb 05, 2003
Posts: 234
Take a look again at what you first tried:

you actually wrote:

which is of course always true.
You are on the right track. It should be:

Where r1 and r2 are the radiuses of both circles.
It says that the center points have to be closer together than the sum of the radiuses.

(How did you come up with the magic number 26?)
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[B][bart]: you actually wrote:

which is of course always true.[/B]

Well, not quite always. Regardless though, the formula has somehow transformed into something unrelated to the solution. His second formula is much closer, but for the mysterious 26.
[ October 22, 2007: Message edited by: Jim Yingst ]
Mark Quin
Greenhorn

Joined: Oct 21, 2007
Posts: 15
"In your last formula, where does the number 26 come from?"
I checked what was one of the closest numbers to the edge of the circle.


Ha ha, that was probably because I have been trying all kinds of combinations.

Anyways, I just tried this again. I had tried this before:
r1=30/2
r2=20/2


It does not seem to work right. It says there is a Collision Detected everywhere except within close proximity to the other circle. Also, it still does not have to touch the other circle at all to trigger a change.
With a change in signs:

It simply is saying there is a collision when it is in the general area of the circle.

I notice that it is not centered right. Look how it detects it farther away on the left side then the right for some reason:
Left:

Right:



Here is my class sorry about the mess, I have been trying so many things:


[ October 22, 2007: Message edited by: Mark Quin ]
[ October 22, 2007: Message edited by: Mark Quin ]
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

You use g.fillOval(snakexpos, snakeypos, snakewidth, snakeheight);
This makes (snakexpos,snakeypos) the top-left corner of the rectangle enclosing the circle, and snakewidth and snakeheight are the radius * 2.

So basically, the center of your circle is at (snakexpos + snakewidth / 2, snakeypos + snakeheight / 2) with radius snakewidth / 2.

You should use that position and that radius when calculating the collision, not snakexpos, snakeypos, snakewidth and snakeheight.


Also, your code allows for non-circle ellipses if you happen to change either snakewidth or snakeheight but not both. This will make detecting the collection a tad more difficult. Just use one variable for both sizes and you'll ensure it'll always be a circle.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Jim]: In your last formula, where does the number 26 come from?

[Mark]: I checked what was one of the closest numbers to the edge of the circle.


Well, that sounds kind of vague. What is the closest possible number to the edge of the circle? Or rather, what is the distance where the two circles are just touching?

[Mark]: With a change in signs:

It sounds like you're now changing things randomly to see what happens, and getting farther from the solution in the process. In choosing between < and >, one of those makes sense, and the other doesn't.

[B][Mark]: [/B]

Where did the 35 come from? Another mysterious magic number?

It seems like you've probably had the correct solution here at some point, or very close, but you keep changing things around in so many different ways, it's hard to keep straight what you're doing. From what you said, the original code with the number 26 was fairly close to the correct answer, just a little bit off. Which i swhy I asked where the 26 came from. There's another number that would work better here. You've even written the formula down for it. I don't know why your code hasn't worked yet, because it seems like you've tried the correct formula, but I'm guessing you've now got too much debris from past random changes littering up your code, and overlooked some change that shouldn't be there.
[ October 22, 2007: Message edited by: Jim Yingst ]
Mark Quin
Greenhorn

Joined: Oct 21, 2007
Posts: 15
Well, that sounds kind of vague.
It was a bit vague, I just took the distance where it appeared to be just touching the edge of the other circle.

It sounds like you're now changing things randomly to see what happens

I was not just changing things randomly:
Rob Prime: your first piece of code should work if you change the < symbol to >


Where did the 35 come from?

That was the radii1=15 and radii2=10 15+10=35. I typed it in only because I though there could have been a code artifact.

So, now I have re-worked everything but the bug is still there:


Top Left:

Bottom Left:

Top Right:

Bottom Right:

[ October 22, 2007: Message edited by: Mark Quin ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Jim]: Where did the 35 come from?

[Mark]: That was the radii1=15 and radii2=10 15+10=35.


Ah, 15 + 10 = 25. That's why I was asking about the 26, it was close, but not quite - and then when it changed to 35 that made no sense to me.

All right, the code and results are looking better, and more consistent - that's good. i think the missing piece now is that you need to look again at Rob Prime's last post. There is an important difference between the coordinates of the upper left corner of an oval (circle), and the center of the oval, and I believe this probably accounts for the small error you're still seeing here.

If you continue to have problems with this, please show us the code that draws the black circle, the one with diameter 20 (apparently). I think you need to distinguish between the center and the upper left corner, for both of the circles you're drawing here. The fillOval() method expects you to identify where the upper left corner is, but your distance formula makes more sense if you're talking about the center of each circle. So think abou texactly hwere each off those circles really is. I hope that helps.
Mark Quin
Greenhorn

Joined: Oct 21, 2007
Posts: 15
How exactly can I compensate for Java drawing it from the top left corner? I am new to using Java.

The code for the black ball is quite small.


[ October 22, 2007: Message edited by: Mark Quin ]
[ October 22, 2007: Message edited by: Mark Quin ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
There are a couple different ways to do this depending on how you're thinking of the variables. What do xpos and ypos refer to? Are they the coordinates of the center of the 30-diameter circle, or are they the coordinates of the upper left corner or the enclosing rectangle? And similarly, what do x and y mean? Coordinates of the center of the 20-diameter circle, or coordinates of the upper left corner or the enclosing rectangle? I think Rob assumes they were both the corners, because of how you used fillOval(). And he described how to change the collision calculation as a result.

Alternately, you can assume they refer to the centers of the two circles - in which case the collision calculation is fine, but you need to change how you use fillOval(). Basically, fillOval expects the first two arguments to refer to the upper left hand corner of the enclosing rectangle. So you need to figure out where that is. If a the "snake" is a circle of diameter 30 with center at xpos, ypos, then its upper left corner must be at (xpos - 15, ypose + 15). So for fillOval() you'd use

g.fillOval(xpos - 15, ypos + 15, 15, 15);

And if the "person" is a circle of diameter 20 located at x, y, then its upper left corner is at (x - 10, y + 10). So for fillOval you'd use

g.fillOval(x - 10, y + 10, 10, 10);

Making those two changes will probably get your graphics to line up with what the calculations say.

You can also replace 15 and 10 with expressions like "diameter/2" or "radius2", whatever. In general that's probably preferable, but I couldn't remember which was which, so I just used the numeric values you'd given.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

Actually that would be g.fillOval(xpos - 15, ypos - 15, 15, 15) and g.fillOval(x - 10, y - 10, 10, 10), seeing as the Java coordinate system has Y increasing as you go down, not up.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Bah - Java is backwards. Just turn your monitor upside down.
greg buela
Ranch Hand

Joined: Sep 04, 2007
Posts: 71
Interesting problem. I remember programming the Commodore 64 which had built in sprite collision detection. Who'd say that 20+ years later there would be a discussion about how to detect collision with a far superior language!


SCJP 1.5
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Circle collision Detection: Solved =)