You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求两圆弧间圆角交点的计算算法:已知圆弧参数与圆角半径

计算两条圆弧间圆角交点的算法方案

先结合你提供的示意图(两条原始圆弧相交,外侧有一段圆角过渡连接它们)来展开说明,核心思路是利用圆与圆的相切关系推导——圆角本质就是和两条原始圆弧都相切的圆,我们要找的就是这个圆角圆与两条原始圆弧的切点(也就是你所说的圆角交点)。

已知条件明确

先把所有已知参数列出来,方便后续推导:

  • 原始圆弧1:圆心坐标 (O_1(x_1, y_1)),半径 (R_1)
  • 原始圆弧2:圆心坐标 (O_2(x_2, y_2)),半径 (R_2)
  • 圆角半径 (r)
  • 两条原始圆弧的交点(用来辅助判断圆角的过渡方向)

分步推导过程

步骤1:确定圆角圆的圆心位置

圆角圆的圆心 (O_0) 必须满足两个核心条件:

  • 到 (O_1) 的距离 = (D_1 = R_1 + r)(外圆角,也就是你图里的情况,圆角在两条圆弧外侧过渡);如果是内圆角(在圆弧内侧过渡),则 (D_1 = |R_1 - r|)
  • 到 (O_2) 的距离 = (D_2 = R_2 + r)(外圆角);内圆角则 (D_2 = |R_2 - r|)

所以 (O_0) 就是以 (O_1) 为圆心、(D_1) 为半径的圆,和以 (O_2) 为圆心、(D_2) 为半径的圆的交点。计算坐标的具体步骤:

  1. 计算两原始圆心的距离 (d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2})
  2. 先验证可行性:必须满足 (|D_1 - D_2| \leq d \leq D_1 + D_2),否则这个半径的圆角无法构造
  3. 计算辅助参数:
    • (a = \frac{D_1^2 - D_2^2 + d^2}{2d})
    • (h = \sqrt{D_1^2 - a^2})(处理浮点误差时,若根号内为负则取0)
  4. 得到两个可能的圆心坐标,根据你的示意图选择符合过渡方向的那个:
    • 第一个候选:(O_0(x_1 + \frac{a(x_2-x_1)}{d} + \frac{h(y_2-y_1)}{d}, y_1 + \frac{a(y_2-y_1)}{d} - \frac{h(x_2-x_1)}{d}))
    • 第二个候选:(O_0(x_1 + \frac{a(x_2-x_1)}{d} - \frac{h(y_2-y_1)}{d}, y_1 + \frac{a(y_2-y_1)}{d} + \frac{h(x_2-x_1)}{d}))

步骤2:计算圆角与圆弧1的切点A

切点A必然在 (O_1) 和 (O_0) 的连线上,且到 (O_1) 的距离为 (R_1),到 (O_0) 的距离为 (r):

  1. 计算向量 ( \overrightarrow{O_1O_0} = (x_0 - x_1, y_0 - y_1) ),然后归一化为单位向量 ( \vec{u} = \frac{\overrightarrow{O_1O_0}}{|\overrightarrow{O_1O_0}|} )
  2. 外圆角情况:( A = (x_1 + u_x \cdot R_1, y_1 + u_y \cdot R_1) )
  3. 内圆角情况:若 ( R_1 > r ),方向和外圆角一致;若 ( R_1 < r ),则取反方向:( A = (x_1 - u_x \cdot R_1, y_1 - u_y \cdot R_1) )

步骤3:计算圆角与圆弧2的切点B

和步骤2逻辑完全一致:

  1. 计算向量 ( \overrightarrow{O_2O_0} = (x_0 - x_2, y_0 - y_2) ),归一化为单位向量 ( \vec{v} = \frac{\overrightarrow{O_2O_0}}{|\overrightarrow{O_2O_0}|} )
  2. 外圆角情况:( B = (x_2 + v_x \cdot R_2, y_2 + v_y \cdot R_2) )
  3. 内圆角情况:根据 ( R_2 ) 和 ( r ) 的大小调整方向,确保到 ( O_2 ) 的距离为 ( R_2 )

验证与注意事项

  • 要确认切点A、B确实在对应的原始圆弧段上(而不是整个圆的其他部分),可以通过计算切点到原始圆弧交点的弧长,或者判断向量夹角是否符合圆弧的走向(顺时针/逆时针)来验证。
  • 如果原始两条圆弧有多个交点,一定要根据实际需求选择正确的圆角圆心(两个候选里选对应过渡区域的那个)。

伪代码实现示例

import math

def calculate_fillet_points(O1, R1, O2, R2, r, fillet_type="outer"):
    """
    计算两条圆弧间圆角的切点及圆角圆心
    参数:
        O1: 圆弧1的圆心,元组(x, y)
        R1: 圆弧1的半径
        O2: 圆弧2的圆心,元组(x, y)
        R2: 圆弧2的半径
        r: 圆角半径
        fillet_type: 圆角类型,"outer"外圆角,"inner"内圆角
    返回:
        (切点A, 切点B, 圆角圆心O0)
    """
    x1, y1 = O1
    x2, y2 = O2
    
    # 计算圆角圆到原始圆心的距离
    if fillet_type == "outer":
        D1 = R1 + r
        D2 = R2 + r
    else:
        D1 = abs(R1 - r)
        D2 = abs(R2 - r)
    
    # 计算两原始圆心的距离
    dx = x2 - x1
    dy = y2 - y1
    d = math.hypot(dx, dy)
    
    # 检查圆角是否可构造
    if abs(D1 - D2) > d or d > D1 + D2:
        raise ValueError("该半径的圆角无法构造,两圆无交点")
    
    # 计算圆角圆心坐标
    a = (D1**2 - D2**2 + d**2) / (2 * d)
    h_sq = D1**2 - a**2
    h_sq = max(h_sq, 0)  # 处理浮点精度问题
    h = math.sqrt(h_sq)
    
    # 取第一个候选圆心(可根据实际需求切换到第二个)
    x0 = x1 + a * dx / d + h * dy / d
    y0 = y1 + a * dy / d - h * dx / d
    # 第二个候选圆心:x0 = x1 + a*dx/d - h*dy/d; y0 = y1 + a*dy/d + h*dx/d
    
    # 计算圆弧1的切点A
    vec_O1O0 = (x0 - x1, y0 - y1)
    len_O1O0 = math.hypot(*vec_O1O0)
    ux, uy = vec_O1O0[0]/len_O1O0, vec_O1O0[1]/len_O1O0
    if fillet_type == "outer" or R1 > r:
        A = (x1 + ux * R1, y1 + uy * R1)
    else:
        A = (x1 - ux * R1, y1 - uy * R1)
    
    # 计算圆弧2的切点B
    vec_O2O0 = (x0 - x2, y0 - y2)
    len_O2O0 = math.hypot(*vec_O2O0)
    vx, vy = vec_O2O0[0]/len_O2O0, vec_O2O0[1]/len_O2O0
    if fillet_type == "outer" or R2 > r:
        B = (x2 + vx * R2, y2 + vy * R2)
    else:
        B = (x2 - vx * R2, y2 - vy * R2)
    
    return (A, B, (x0, y0))

内容的提问来源于stack exchange,提问作者James W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:10:40