寻找直线和圆的交点

Finding intersection points of line and circle

我想了解这个函数的作用。它是我的老师给出的,我只是无法理解,找到 x 和 y 坐标的公式背后的逻辑是什么。从我的数学 class 我知道我找到拦截的公式,但它在代码中的翻译令人困惑。所以我对他们如何定义 a、b、c 的公式以及如何找到坐标 x 和 y 有一些疑问。

void Intersection::getIntersectionPoints(const Arc& arc, const Line& line) {
  double a, b, c, mu, det;

  std::pair<double, double> xPoints;
  std::pair<double, double> yPoints;
  std::pair<double, double> zPoints;

//(m2+1)x2+2(mc−mq−p)x+(q2−r2+p2−2cq+c2)=0.
  //a= m2;
  //b= 2 * (mc - mq - p);
  //c= q2−r2+p2−2cq+c2
  a = pow((line.end().x - line.start().x), 2) + pow((line.end().y - line.start().y), 2) + pow((line.end().z - line.start().z), 2);

  b = 2 * ((line.end().x - line.start().x)*(line.start().x - arc.center().x)
    + (line.end().y - line.start().y)*(line.start().y - arc.center().y)
    + (line.end().z - line.start().z)*(line.start().z - arc.center().z));

  c = pow((arc.center().x), 2) + pow((arc.center().y), 2) +
    pow((arc.center().z), 2) + pow((line.start().x), 2) +
    pow((line.start().y), 2) + pow((line.start().z), 2) -
    2 * (arc.center().x * line.start().x + arc.center().y * line.start().y +
    arc.center().z * line.start().z) - pow((arc.radius()), 2);

  det = pow(b, 2) - 4 * a * c;

  /* Tangenta na kružnicu */
  if (Math<double>::isEqual(det, 0.0, 0.00001)) {
    if (!Math<double>::isEqual(a, 0.0, 0.00001))
      mu = -b / (2 * a);
    else
      mu = 0.0;
 //                              x =      h         +  t *   ( p         −       h )
    xPoints.second = xPoints.first = line.start().x + mu * (line.end().x - line.start().x);
    yPoints.second = yPoints.first = line.start().y + mu * (line.end().y - line.start().y);
    zPoints.second = zPoints.first = line.start().z + mu * (line.end().z - line.start().z);
  }

  if (Math<double>::isGreater(det, 0.0, 0.00001)) {
    // first intersection
    mu = (-b - sqrt(pow(b, 2) - 4 * a * c)) / (2 * a);
    xPoints.first = line.start().x + mu * (line.end().x - line.start().x);
    yPoints.first = line.start().y + mu * (line.end().y - line.start().y);
    zPoints.first = line.start().z + mu * (line.end().z - line.start().z);
    // second intersection

    mu = (-b + sqrt(pow(b, 2) - 4 * a * c)) / (2 * a);
    xPoints.second = line.start().x + mu * (line.end().x - line.start().x);
    yPoints.second = line.start().y + mu * (line.end().y - line.start().y);
    zPoints.second = line.start().z + mu * (line.end().z - line.start().z);
  }

设直线起点为A,终点为B,圆心为C,圆半径为r,交点为P,则P可写为

   P=(1-t)*A + t*B = A+t*(B-A)   (1)

点P也位于圆上,因此

   |P-C|^2 = r^2                 (2)

将方程(1)代入方程(2),得到

   |B-A|^2*t^2 + 2(B-A)\dot(A-C)*t +(|A-C|^2 - r^2) = 0    (3)

这就是您在发布的程序中获得 a、b 和 c 的公式的方法。求解 t 后,您应从等式(1)中获得交点。由于等式 (3) 是二次方程,您可能会得到 0、1 或 2 个 t 值,这对应于线可能不与圆相交、与圆完全相切或在两个位置穿过圆的几何配置。