1

Edit: I could divide the radius with the angle?

Problem: For the sake of learning the arts of collision in HTML5 Canvas, I am currently trying to get a full circle to collide with a segmented circle, in this case a semi circle.

What I Tried: My first thought was a simple circle to circle collision would do but I was wrong. I read various sources on collision detection but all of them were either the standard circle / circle, box / circle, box / box, or polygon collision formulas.

My Question: What is the formula for colliding a full circle with only a segmented circle? It seems something other than just the radius comes into play. Maybe the radians as well?

Attempt:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var C1 = {x: 45, y: 65, radius: 20};
var C2 = {x: 60, y: 20, radius: 20};

var dx = C1.x - C2.x;
var dy = C1.y - C2.y;
var distance = Math.sqrt(dx * dx + dy * dy);

ctx.beginPath();
ctx.arc(C1.x, C1.y, C1.radius, 0, Math.PI * 2);
ctx.fillStyle = 'green';
ctx.fill();

ctx.beginPath();
ctx.rotate(0.3); 
ctx.arc(C2.x, C2.y, C2.radius, 0, Math.PI * 1);
ctx.fillStyle = 'red';
ctx.fill();

if (distance < C1.radius + C2.radius) {
    alert('true')
}
else {
    alert('false')
}

A demo for to play around with: jsfiddle.net/tonyh90g/1

My learning resource: https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection

1
  • @squint maybe you are interested in checking this out Commented Oct 26, 2015 at 9:54

1 Answer 1

1

You're on the right tracks, you will indeed need to not only calculate the distance between centres but also the angle of the intersection point(s) on the segment.

In general cartesian coordinates that angle can be calculated using Math.atan2(dy, dx) where dx and dy are the difference in coordinates from the segment to the circle. If those angles fall between the segment's angle, you have a hit.

[NB: At the exact point of touching there's only one point, but if the two objects end up slightly overlapping, which is not uncommon in animation, you'll get two points].

It's also possible that the circle could intersect the line segments rather than the round portion of the segment, but I think those cases will be correctly caught anyway. This may require further investigation, and if required would need a line-segment / circle intersection test.

I also note in your fiddle that you're using rotate() transforms on the sector. This will foul up your angle calculations unless you specifically account for it. It may be easier to use absolute angles throughout.

Sign up to request clarification or add additional context in comments.

8 Comments

What I am trying to do is simply detect when they collide (exact point of touching) but not intersect. Could you post a simple example so that I can understand how to incorporate the angle?
I could divide the radius with the angle
@asperger no, that won't work - you'd need to use Math.atan2(dy, dx) where dy and dx are the differences between the circle centers. Also pay attention to the fact that y coordinates go positive downwards, whereas standard cartesian coordinates use y positive upwards.
I used your formula. Please let me know if the implementation is correct. jsfiddle.net/tonyh90g/7 and I will accept your answer
@Asperger I don't know why you think you need to divide by anything - you need to test for semi >= 0 && semi < C2.angle (and also the distance test), but only once you've corrected for the Y-axis direction, and made sure that dx and dy have the right sign (otherwise your angles will be 180 degrees out)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.