如何获取UIBezierPath圆弧起止点距离?已知参数时怎么计算?
计算UIBezierPath圆弧起点与终点的直线距离
嘿,这个问题本质上是个几何计算问题,不用太纠结UIBezierPath的API,直接通过已知的圆心、半径、角度就能轻松算出结果,甚至比从路径里取点更可靠!
核心思路:利用几何定理简化计算
已知圆心坐标、半径、起始/结束角度(注意iOS中角度是弧度制,0指向右侧,顺时针为正方向),我们可以通过两种方式计算两点间的直线距离:
方法1:先算坐标再用距离公式
- 先分别计算起点和终点的坐标:
- 起点坐标:
startX = cx + r * cos(startAngle),startY = cy + r * sin(startAngle) - 终点坐标:
endX = cx + r * cos(endAngle),endY = cy + r * sin(endAngle)
- 起点坐标:
- 代入两点间距离公式:
distance = sqrt( (endX - startX)² + (endY - startY)² )
方法2:用圆心角直接计算(更高效)
这种方法不用计算坐标,利用余弦定理推导而来:
- 先计算两个角度的差值
deltaAngle = |endAngle - startAngle| - 因为两点间的最短距离对应小弧的圆心角,所以如果
deltaAngle > π(180度),取deltaAngle = 2π - deltaAngle - 代入公式:
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
相关产品推荐
相关产品推荐

