查找直线和圆的交点

时间:2016-06-10 08:02:05

标签: line geometry intersection

我试图了解这个功能的作用。这是由我的老师给出的,我不能理解,找到x和y坐标的公式背后的逻辑是什么。从我的数学课上我知道我的寻找拦截的公式,但它在代码中被翻译成混乱。所以我有一些问题,他们如何定义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);
  }

1 个答案:

答案 0 :(得分:0)

将线的起点表示为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)是二次方程式,因此t可能得到0,1或2个值,这些值对应于线可能不与圆相交的几何配置,与圆完全相切或通过圆在两个位置传递。