切线从外部点。圈

时间:2014-01-13 08:50:43

标签: c++ math opencv geometry

我想绘制一个圆的两条切线,其中心(x1,y1)和半径(r)是已知的,切线穿过外部点(x0,y0)。鉴于上述信息我怎样才能找到这两条线与圆的相切点。提前致谢

P.S。我需要在C ++中执行此操作

2 个答案:

答案 0 :(得分:0)

虽然我同意这个问题不在话题而应该关闭,但我会发布一个答案,因为它可能仍有帮助。

以下是我要做的事情:我会计算圆圈的polar line,您可以通过将matrix representation of the circle乘以该点的homogeneous coordinates得到,即(x0) ,y0,1)。结果向量(a,b,c)描述了一条线{(x,y)| ax + by + c = 0},你可以将它与圆相交以找到你的相切点。

上述内容不仅适用于圆圈,也适用于任意流畅的conics

答案 1 :(得分:0)

在实践中计算切点的一些线索:

  1. 将所有点移动到以零为中心的圆圈(P' = P0 - Center
  2. 缩放以制作单位半径圆(x^2+y^2=1, P = P'/Renter image description here
  3. 来自坐标的半径矢量。原点到切点垂直于切线,因此它们的标量乘积为零:

    x*(X-x)+y*(Y-y)=0
    x*X + y*Y = x^2 +y^2 = 1    
    y = (1 - x*X)/Y
    
  4. 用圆方程代替y,求解x的这个二次方程,然后求y

    x^2*(X^2+Y^2)+x*(-2X)+(1-Y^2)=0
    
  5. 恢复原始比例和偏移

  6. 德尔福实施:

    //finds tangent points to circle from external point (XX, YY)
    //returns number of tangents (0, 1, 2)
    function GetTangentPointsAtCircle(CenterX, CenterY, R, XX, YY: Double;
                                     var XT0, YT0, XT1, YT1: Double): Integer;
    var
      nx, ny, xy, tx0, tx1, D: Double;
    begin
      if R = 0 then //this behavior can be modified
        Exit(0);
    
      nx := (XX - CenterX) / R; //shift and scale
      ny := (YY - CenterY) / R;
      xy := nx * nx + ny * ny;
    
      if Math.SameValue(xy, 1.0) then begin //point lies at circumference, one tangent
        XT0 := XX;
        YT0 := YY;
        Exit(1);
      end;
    
      if xy < 1.0 then  //point lies inside the circle, no tangents
        Exit(0);
    
      //common case, two tangents
      Result := 2;
      D := ny * Sqrt(xy - 1);
      tx0 := (nx - D) / xy;
      tx1 := (nx + D) / xy;
      if ny <> 0 then begin //common case
        YT0 := CenterY + R * (1 - tx0 * nx) / ny;
        YT1 := CenterY + R * (1 - tx1 * nx) / ny;
      end else begin //point at the center horizontal, Y=0
        D := R * Sqrt(1 - tx0 * tx0);
        YT0 := CenterY + D;
        YT1 := CenterY - D;
      end;
      XT0 := CenterX + R * tx0; //restore scale and position
      XT1 := CenterX + R * tx1;
    end;