I figured one approach would be to divide the trapezoid in three parts, two triangles and a rectangle in the middle.

enter image description here

Then for the circle-rectangle case I would check collision like this:

function testCircleRectCollision(circle, rect) {
    closestX = clamp(circle.x, rect.left, rect.right)
    closestY = clamp(circle.y, rect.top, rect.bottom)

    distanceX = circle.x - closestX
    distanceY = circle.y - closestY

    return pow(distanceX, 2) + pow(distanceY, 2) < pow(circle.radius, 2)

For the circle-trangle case, I could only think of checking if the vertices of the triangle are inside the circle like this:

function vertexInCircle(circle, v) {
    return pow(v.x - circle.x, 2) + pow(v.y - circle.y, 2) < pow(circle.radius, 2)

But I still need to check two cases: 1) if the circle is completely inside the rectangle and 2) if the circle is intersecting with any of the triangle's edges. How can I do this?

Or is there a better way to check for circle-trapezoid collision?


1 Answer 1


I'd go with splitting it into two triangles by connecting two opposite points and using two triangle-circle intersection tests.

Those tests needs to cover three cases:

  1. A vertex of the triangle is inside the circle.
  2. The circle is contained within the triangle.
  3. An edge of the triangle intersects the circle.

The first part is easy - just calculate distances from the corners of the triangle to centre of the circle and compare to the radius.

For the second and third cases you need to test for intersections between the triangle edge lines and the circle, as well as working out which side of each line the circle is on.

The main advantage of testing on triangles is that you can reuse the code with any polygonal shape, although the triangulation itself can be complicated if it's not a convex polygon.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .