首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确定直线段是否与圆相切?

如何确定直线段是否与圆相切?
EN

Stack Overflow用户
提问于 2016-07-27 11:25:33
回答 3查看 1.3K关注 0票数 2

我有一个原点为(cx,cy)的圆。半径是r。然后,有一条由两点定义的线段:(x1,y1)和(x2,y2)。如何确定直线段(不是延长线)是否与圆相切?如果是,这两个人在哪里接触?

我现在要做的是:找出点(cx,cy)到延伸线的距离。如果距离!= r,那么直线段肯定不与圆相切。即使距离== r,我们也需要找出它们相交的点。然后检查该点是否位于(x1,y1)和(x2,y2)之间的线段上。如果是,则直线段与圆相切-并且已经计算出接触点。这是可行的,但涉及到太多的数学运算。并且所有变量都是浮点型或双精度型变量。有没有更智能、更快的算法来达到同样的效果?

谢谢和问候,普拉莫德

EN

回答 3

Stack Overflow用户

发布于 2016-07-27 13:49:55

我建议你停止对斜率的推理,因为在垂直方向上的奇点总是令人讨厌的。请尝试使用参数化形式:

代码语言:javascript
复制
p = p1 + t v   where   v = p2 - p1

现在将向量p1 - c投影到v上,取导数wrt t,设置为0,您很快就得到了t的值的表达式,该表达式描述了无穷大直线上最接近c的点,这是切点:

代码语言:javascript
复制
    (c - p1) dot v
t = --------------
       v dot v

如果该值介于0和1之间,则切点位于p1p2之间。这是一个非常便宜的计算。如果是真的,您可以继续进行半径检查

代码语言:javascript
复制
(c - p1 - tv) dot (c - p1 - tv) ~= r^2  ?

请注意,上面已经计算了子项c - p1

您提到只有圆在移动,所以您可以计算一次v dot v并保存它。

票数 3
EN

Stack Overflow用户

发布于 2016-07-27 12:40:24

您可能知道这样一个属性:如果f(x,y) = y-m*x-c是直线段,则|f(x1,y1)|/sqrt(1+m^2)表示直线到(x1,y1)的距离。因此:

代码语言:javascript
复制
double m = (y2-y1)/(x2-x1);//slope
double c = y1 - m*x1;//since (x1,y1) lies on the line f(x1,y1) is zero
double d = abs(cy - m*cx - c)/sqrt(1+m*m);//distance
if(d==r)//radius
 //Yeah its tangent and do whatever you want
else
 //Nope

对于第二部分,伪代码;

代码语言:javascript
复制
g1(x,y) = y+(1/m)*x-c1;//perpendicular line through (x1,y1)
g2(x,y) = y+(1/m)*x-c2;//perpendicular line through (x2,y2)
c1 = y1+(1/m)*x1;
c2 = y2+(1/m)*x2;
if(g1(cx,cy)*g2(cx,cy)<0)//condition if point lies between two lines.Here make sure the coeffecients of y and x are of same sign in g1 and g2
//yes
else
//no
票数 2
EN

Stack Overflow用户

发布于 2016-07-27 11:57:39

根据定义,切线必须垂直于半径线。在下图中,红线是切线,当且仅当它垂直于绿线(从中心到接触点)。

因此,如果您知道切线M的坡度(根据(x1,y1)(x2,y2)计算),则半径线的坡度为-1/M。假设你知道

计算接触点很容易。实际上,有两个可能的接触点,在圆的两边。

因此,您需要做的就是检查两个可能的接触点中是否有一个在线段上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38603185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档