Circle line-segment collision detection algorithm?

前端 未结 28 1302
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 06:38

I have a line from A to B and a circle positioned at C with the radius R.

\"Image\"

What is a good alg

28条回答
  •  囚心锁ツ
    2020-11-22 06:56

    You can find a point on a infinite line that is nearest to circle center by projecting vector AC onto vector AB. Calculate the distance between that point and circle center. If it is greater that R, there is no intersection. If the distance is equal to R, line is a tangent of the circle and the point nearest to circle center is actually the intersection point. If distance less that R, then there are 2 intersection points. They lie at the same distance from the point nearest to circle center. That distance can easily be calculated using Pythagorean theorem. Here's algorithm in pseudocode:

    {
    dX = bX - aX;
    dY = bY - aY;
    if ((dX == 0) && (dY == 0))
      {
      // A and B are the same points, no way to calculate intersection
      return;
      }
    
    dl = (dX * dX + dY * dY);
    t = ((cX - aX) * dX + (cY - aY) * dY) / dl;
    
    // point on a line nearest to circle center
    nearestX = aX + t * dX;
    nearestY = aY + t * dY;
    
    dist = point_dist(nearestX, nearestY, cX, cY);
    
    if (dist == R)
      {
      // line segment touches circle; one intersection point
      iX = nearestX;
      iY = nearestY;
    
      if (t < 0 || t > 1)
        {
        // intersection point is not actually within line segment
        }
      }
    else if (dist < R)
      {
      // two possible intersection points
    
      dt = sqrt(R * R - dist * dist) / sqrt(dl);
    
      // intersection point nearest to A
      t1 = t - dt;
      i1X = aX + t1 * dX;
      i1Y = aY + t1 * dY;
      if (t1 < 0 || t1 > 1)
        {
        // intersection point is not actually within line segment
        }
    
      // intersection point farthest from A
      t2 = t + dt;
      i2X = aX + t2 * dX;
      i2Y = aY + t2 * dY;
      if (t2 < 0 || t2 > 1)
        {
        // intersection point is not actually within line segment
        }
      }
    else
      {
      // no intersection
      }
    }
    

    EDIT: added code to check whether found intersection points actually are within line segment.

提交回复
热议问题