已知圆外一点,圆心和半径,求过圆外点的直线与圆的切点算法

CPoint CalcQieDian(CPoint ptCenter, CPoint ptOutside, double dbRadious) 
{ 
    struct point {double x, y;};
 point E,F,G,H;
 double r=dbRadious;
 //1. 坐标平移到圆心ptCenter处,求园外点的新坐标E
 E.x= ptOutside.x-ptCenter.x;
 E.y= ptOutside.y-ptCenter.y; //平移变换到E
 
 //2. 求园与OE的交点坐标F, 相当于E的缩放变换
 double t= r / sqrt (E.x * E.x + E.y * E.y);  //得到缩放比例
 F.x= E.x * t;   F.y= E.y * t;   //缩放变换到F

 //3. 将E旋转变换角度a到切点G,其中cos(a)=r/OF=t, 所以a=arccos(t);
 double a=acos(t);   //得到旋转角度
 G.x=F.x*cos(a) -F.y*sin(a);
 G.y=F.x*sin(a) +F.y*cos(a);    //旋转变换到G

 //4. 将G平移到原来的坐标下得到新坐标H
 H.x=G.x+ptCenter.x;
 H.y=G.y+ptCenter.y;             //平移变换到H
    
 //5. 返回H
 return CPoint(int(H.x),int(H.y));
 //6. 实际应用过程中,只要一个中间变量E,其他F,G,H可以不用。
}

应该说方法有很多种,几何的,代数的,做的过程中也在纸上运算了好长时间,可能也是这些知识很久没用了,生疏很多。解出来的公式都比较复杂,无意间在网上找到这个方法,没经过具体的笔算验证,但是求出来的结果是我预判范围的,暂定为计算结果是正确的。在这边共享下,有需要的童鞋不妨自己验证一下。

对了,这个函数只能返回一个点,理论上有两个切点的,只要把15行改成如下:

 double a=-acos(t);   //得到旋转角度


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值