想要使用 UIBezierPath 绘制说明符号

Want to draw explanatory sign using UIBezierPath

我需要使用 UIBezierPath 绘制说明符号。

我想画的是

我正在使用下面的代码

private func linePath()-> CGPath {
        let viewCenter = CGPoint(x: bounds.midX, y: bounds.midY)
        
        let radius = bounds.midX/7.5
        
        let miniRadius = bounds.midX/15
        
        
        
        let path = UIBezierPath()
        ///path.move(to: viewCenter)
        path.addArc(withCenter: viewCenter, radius: miniRadius, startAngle: 0, endAngle: 180.degreesToRadians, clockwise: true)
        
        
        path.addQuadCurve(to: CGPoint(x: path.currentPoint.x - 5, y: path.currentPoint.y - 30), controlPoint: CGPoint(x: path.currentPoint.x - 10, y: path.currentPoint.y - 30))
        
       // path.addLine(to: CGPoint(x: path.currentPoint.x - 5, y: path.currentPoint.y - 30))
        
        path.addArc(withCenter: CGPoint(x: path.currentPoint.x + radius, y: path.currentPoint.y + radius/2), radius: radius, startAngle: 180, endAngle: 0.degreesToRadians, clockwise: true)
        
        path.close()
        return path.cgPath
    }

感谢任何帮助或指点。

使用贝塞尔曲线绘制平滑形状时,我们要确保在一条曲线与另一条曲线相邻的整个路径中没有斜率的不连续点。即,我们要确保没有任何点 start/end 点前后的斜率不相等。

简而言之,确保每条贝塞尔曲线的第一个控制点的斜率与前一条曲线的斜率匹配(当然,第二个控制点与下一条曲线的斜率匹配)。

考虑以下内容,描边三个路径,一个圆弧和两个立方贝塞尔曲线(加上描边贝塞尔曲线的控制点):

我已经用三个曲线完成了这个,我用深色线显示了绿色和黄色曲线的控制点。顺时针方向,注意黄色曲线的第一个控制点如何与蓝色弧的切线共线。黄色的第二个控制点与绿色曲线的第一个控制点共线。当然,绿色曲线的第二个控制点与蓝色曲线的起始切线共线。

摆脱产生的分散注意力的颜色:

仅供参考,这生成了以上内容:

func updatePath() {
    let verticalControlOffset = radius
    let horizontalControllOffset = radius / 2
    let height = radius * 5

    let path = UIBezierPath()
    path.addArc(withCenter: CGPoint(x: bounds.midX, y: bounds.minY + radius),
                radius: radius,
                startAngle: .pi,
                endAngle: 2 * .pi,
                clockwise: true)

    var startPoint = path.currentPoint
    var endPoint = CGPoint(x: bounds.midX, y: bounds.minY + height)
    var cp1 = CGPoint(x: startPoint.x, y: startPoint.y + verticalControlOffset)
    var cp2 = CGPoint(x: endPoint.x + horizontalControllOffset, y: endPoint.y)

    path.addCurve(to: endPoint,
                  controlPoint1: cp1,
                  controlPoint2: cp2)

    startPoint = path.currentPoint
    endPoint = CGPoint(x: bounds.midX - radius, y: bounds.minY + radius)
    cp1 = CGPoint(x: startPoint.x - horizontalControllOffset, y: startPoint.y)
    cp2 = CGPoint(x: endPoint.x, y: endPoint.y + verticalControlOffset)

    path.addCurve(to: endPoint,
                  controlPoint1: cp1,
                  controlPoint2: cp2)

    shapeLayer.path = path.cgPath
}

现在,这与您的目标形状并不完全相同。但它说明了问题,即当将一系列贝塞尔曲线连接在一起时,确保相邻曲线的控制点彼此对齐。当您的控制点都是垂直和水平时,这很容易,但如果不是,您将需要使用一点代数 and/or 三角函数来确保它们正确排列。有时,在渲染复杂的形状时,在控制点上画线会很有帮助,这样您就可以很容易地看到正在发生的事情。