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

如何获取UIBezierPath圆弧起止点距离?已知参数时怎么计算?

计算UIBezierPath圆弧起点与终点的直线距离

嘿,这个问题本质上是个几何计算问题,不用太纠结UIBezierPath的API,直接通过已知的圆心、半径、角度就能轻松算出结果,甚至比从路径里取点更可靠!

核心思路:利用几何定理简化计算

已知圆心坐标、半径、起始/结束角度(注意iOS中角度是弧度制,0指向右侧,顺时针为正方向),我们可以通过两种方式计算两点间的直线距离:

方法1:先算坐标再用距离公式

  1. 先分别计算起点和终点的坐标:
    • 起点坐标:startX = cx + r * cos(startAngle),startY = cy + r * sin(startAngle)
    • 终点坐标:endX = cx + r * cos(endAngle),endY = cy + r * sin(endAngle)
  2. 代入两点间距离公式:
    distance = sqrt( (endX - startX)² + (endY - startY)² )

方法2:用圆心角直接计算(更高效)

这种方法不用计算坐标,利用余弦定理推导而来:

  1. 先计算两个角度的差值deltaAngle = |endAngle - startAngle|
  2. 因为两点间的最短距离对应小弧的圆心角,所以如果deltaAngle > π(180度),取deltaAngle = 2π - deltaAngle
  3. 代入公式:distance = 2 * r * sin(deltaAngle / 2)

这个公式的原理是:起点、终点、圆心构成一个等腰三角形,两边为半径,顶角是圆心角,通过三角函数直接算出底边长度(也就是两点距离),比方法1少了几次浮点运算,效率更高。

代码示例(Swift)

func arcStartEndDistance(center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat) -> CGFloat {
    var deltaAngle = abs(endAngle - startAngle)
    // 确保取的是最小的圆心角(不超过π)
    if deltaAngle > .pi {
        deltaAngle = 2 * .pi - deltaAngle
    }
    return 2 * radius * sin(deltaAngle / 2)
}

代码示例(Objective-C)

CGFloat arcStartEndDistance(CGPoint center, CGFloat radius, CGFloat startAngle, CGFloat endAngle) {
    CGFloat deltaAngle = fabs(endAngle - startAngle);
    if (deltaAngle > M_PI) {
        deltaAngle = 2 * M_PI - deltaAngle;
    }
    return 2 * radius * sin(deltaAngle / 2);
}

补充:关于从UIBezierPath取点的问题

UIBezierPath并没有直接暴露圆弧的起点属性,但调用addArc(withCenter:radius:startAngle:endAngle:clockwise:)之后,path.currentPoint会是圆弧的终点。不过如果路径经过了移动、拼接等操作,这个值可能不准确,所以还是推荐用上面的几何计算方法,结果更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:31:08