Search code examples
javascriptmathcollision-detection

Javascript Collision Detection between circle and polygon?


I'm unsure how to go about defining the area for a collision detection function when I have a polygon that looks like:

    ______
   / _____|
  / /
 / /
---

I draw the polygon using lineTo() a few times before fill/stroke call so I know the x,y co-ords of all the points.

Currently I just check if the ball is beyond certain areas of points:

    if(tmpParticle.y <= platformBottom) {
        if(tmpParticle.x < leftPipe_middleX || tmpParticle.x > rightPipe_middleX) {
            tmpParticle = particleCollision(tmpParticle, platformBottom);
        }
    }

    if(tmpParticle.y <= pipeBottom && tmpParticle.y >= pipeBottom - 30) {
        if(tmpParticle.x < leftPipe_bottomRightX && tmpParticle.x > leftPipe_bottomLeftX) {
            tmpParticle = particleCollision(tmpParticle, pipeBottom);
        } else if (tmpParticle.x < rightPipe_bottomRightX && tmpParticle.x > rightPipe_bottomLeftX) {
            tmpParticle = particleCollision(tmpParticle, pipeBottom);
        }
    }

platformHeight would be the Y value for the 'top horizontal line' platformBottom would be the Y value for the 'horizontal line just below platformHeight' rightPipe* is for the example shown. leftPipe* is for the same polygon except in the other direction (to form a pipe, where you must shoot the balls through without colliding).

My particleCollision() function just takes the tmpParticle and inverses the direction based on the Y value (2nd parameter, i.e. pipeBottom). This works fine for now though I may need to improve it later on.

I just need to figure out a better way to define the area for collisions.


Solution

  • You may consider splitting your pipe into triangles and then finding triangle - circle intersection area. If they do intersect the intersection will always be a convex polygon (area is easy to calculate by splitting into triangles again) and a segment (area is easy to calculate too - http://en.wikipedia.org/wiki/Circular_segment). The other case is the triangle itself, in case it lies inside the circle completely (a simple case again).