数学 / 直线与圆 · 从方程到位置关系 / 直线与圆的位置关系 待审核 5 / 6
d 与 r · 弦长与切线

直线与圆的位置关系

直线与圆的位置关系有三种。判定有两条路:联立方程消元后看判别式的符号,或者直接比较圆心到直线的距离 dd 与半径 rr。两者等价,后者不必解方程。

1 · 距离与半径的比较

定理 1.1 设圆心到直线的距离为 dd、半径为 rr。则 d>rd > r 时直线与圆相离,d=rd = r 时相切,d<rd < r 时相交。

判据的来历就是圆的定义:圆上的点到圆心的距离恒为 rr,而直线上离圆心最近的点(垂足)距离为 dd。垂足落在圆外则整条直线都在圆外;恰在圆上则它是唯一的公共点;落在圆内则直线从圆内穿出,两侧各交一次。

联立法给出同一个结论。把直线方程代入圆的方程消去一个变量,得到一个一元二次方程,Δ>0\Delta > 0=0= 0<0< 0 分别对应两个、一个、零个公共点。代数上 Δ\Deltar2d2r^2 - d^2 相差一个正因子,故两种判据同号。几何法的好处是不必消元,也不必先讨论「直线是否竖直」——竖直线代入时消去的是另一个变量,联立法要分两种写法。

图 1-1 · 直线与圆的三种关系。可拖动直线的倾斜角与位置观察 ddrr 的比较、弦长的变化;切一栏改为过定点作圆的切线。

2 · 弦长公式

相交时两交点之间的线段是弦。圆心到弦的垂线平分弦,于是半弦、ddrr 构成直角三角形:

弦长=2r2d2\text{弦长} = 2\sqrt{r^2 - d^2}

d=0d = 0 时弦过圆心,弦长取到最大值 2r2r(直径);drd \to r 时弦长趋于零。这个公式把「求弦长」化归成「求点到直线的距离」,比解出两个交点再算距离省得多。

例 2.1(x1)2+(y1)2=4(x-1)^2 + (y-1)^2 = 4 被直线 x+y2=0x + y - 2 = 0 截得的弦长。圆心 (1,1)(1,1) 到直线的距离 d=1+122=0d = \frac{|1 + 1 - 2|}{\sqrt{2}} = 0,直线过圆心,弦长即直径 44。把直线改成 x+y4=0x + y - 4 = 0,则 d=1+142=2d = \frac{|1+1-4|}{\sqrt 2} = \sqrt 2,弦长 242=222\sqrt{4 - 2} = 2\sqrt 2

公式在 dd 略大于 rr 时会失效,而失效的方式不是报错。实测 r=2r = 2d=2.0000001d = 2.0000001r2d2=4.0×107r^2 - d^2 = -4.0 \times 10^{-7},开平方得 NaN。相离时本来就没有弦,所以正确的写法是先分类、再决定要不要算弦长。lineCircle 按这个次序实现:相离与相切两支直接把弦长置零,只有相交那一支才开平方,且被开的量还先与零取大。判定与计算的先后不是风格问题——反过来写,一个 10710^{-7} 量级的浮点误差就能让整个结果变成 NaN

3 · 切线

d=rd = r 时直线与圆相切,切点就是垂足。已知切点求切线只需一步:切线垂直于该点处的半径,故 A=x0aA = x_0 - aB=y0bB = y_0 - b(a,b)(a,b) 为圆心),CC 由过点条件定出。

过一个给定点作切线则要分三种情形:点在圆外有两条,点在圆上一条,点在圆内零条。圆外一点 PP 到切点的距离(切线长)由勾股定理给出:

PT=PC2r2|PT| = \sqrt{|PC|^2 - r^2}

4 · 切点弦:绕开「斜率不存在」

求过圆外一点的两条切线,常见解法是设切线为 yy0=k(xx0)y - y_0 = k(x - x_0),用 d=rd = r 解出 kk。这个解法有一处必须单独讨论:若其中一条切线竖直,它的 kk 不存在,解方程只会得到另一条,答案漏一半。kk 的方程是一元二次的,出现「只有一个根」时就该怀疑漏了竖直的那一条。

tangentLinesFrom 换一条路:先写出切点弦所在的直线

(x0a)(xa)+(y0b)(yb)=r2(x_0 - a)(x - a) + (y_0 - b)(y - b) = r^2

再拿它与圆求交,两个交点就是两个切点,切线由「PP 与切点」两点式给出。这条路上没有斜率出现,竖直的切线只是一个普通的交点。实现上它还复用了 lineCircle——求切点这件事被化归成了上一节的直线与圆求交。

注 · 切点弦这条直线在 PP 落到圆内时依然有方程,且它与圆不相交(此时 PP 到圆心的距离小于 rr,代数上对应无实交点)。这与「圆内一点作不出切线」是一致的,故实现里不必为圆内的情形另设分支,只需在最外层按 PC|PC|rr 的比较先分类:圆内直接返回零条,避免把一个空交点列表当成「有切线但算不出来」。

5 · 参考文献

  1. Line–sphere intersection. Wikipedia. 直线与圆 / 球面求交的一般处理。https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
  2. Tangent lines to circles. Wikipedia. 切线的性质、切线长与过一点的两条切线。https://en.wikipedia.org/wiki/Tangent_lines_to_circles
  3. Chord (geometry). Wikipedia. 弦、弦心距与弦长公式。https://en.wikipedia.org/wiki/Chord_(geometry)