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

如何在iOS/MacOS平台使用Swift计算CGPath与CGRect的相交点

enter image description here
适用平台:iOS 及 MacOS

实现方案

因为需求对结果精度要求不高,这里提供实现成本最低的采样法方案,代码兼容Swift开发,无需引入额外依赖:

核心实现代码

import CoreGraphics

/// 计算规则矩形和圆形的两个交点
/// - Parameters:
///   - circleCenter: 圆形的圆心坐标
///   - radius: 圆形的半径
///   - rect: 目标矩形
/// - Returns: 两个交点,无相交时返回nil
func getRectCircleIntersections(circleCenter: CGPoint, radius: CGFloat, rect: CGRect) -> (p1: CGPoint, p2: CGPoint)? {
    // 前置判断:两个图形的包围盒不相交直接返回
    let circleBounds = CGRect(
        x: circleCenter.x - radius,
        y: circleCenter.y - radius,
        width: radius * 2,
        height: radius * 2
    )
    guard circleBounds.intersects(rect) else { return nil }
    
    let accuracy: CGFloat = 0.5 // 精度值可自行调整,数值越小精度越高
    var resultPoints = [CGPoint]()
    
    // 遍历矩形四条边的采样点
    let edgePoints = [
        // 上边缘
        stride(from: rect.minX, through: rect.maxX, by: accuracy).map { CGPoint(x: $0, y: rect.minY) },
        // 下边缘
        stride(from: rect.minX, through: rect.maxX, by: accuracy).map { CGPoint(x: $0, y: rect.maxY) },
        // 左边缘
        stride(from: rect.minY, through: rect.maxY, by: accuracy).map { CGPoint(x: rect.minX, y: $0) },
        // 右边缘
        stride(from: rect.minY, through: rect.maxY, by: accuracy).map { CGPoint(x: rect.maxX, y: $0) }
    ].flatMap { $0 }
    
    for point in edgePoints {
        // 计算当前点到圆心的距离
        let distance = hypot(point.x - circleCenter.x, point.y - circleCenter.y)
        // 误差范围匹配设置的精度
        if abs(distance - radius) < accuracy {
            resultPoints.append(point)
            if resultPoints.count == 2 { break }
        }
    }
    
    guard resultPoints.count >= 2 else { return nil }
    return (resultPoints[0], resultPoints[1])
}

调用示例

// 示例参数
let circleCenter = CGPoint(x: 100, y: 100)
let radius: CGFloat = 50
let rect = CGRect(x: 50, y: 70, width: 100, height: 60)

if let intersections = getRectCircleIntersections(circleCenter: circleCenter, radius: radius, rect: rect) {
    print("交点1:\(intersections.p1),交点2:\(intersections.p2)")
}

如果你的场景必须基于转换后的CGPath对象计算,也可以用CoreGraphics自带的路径相交判断能力,配合上面的采样逻辑即可实现,不需要额外做贝塞尔曲线的解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:54:05