想使用 UIBezierPath 绘制说明符

问题描述

我需要使用 input : expr {} | input expr expr : CLOSE {if(currentDepth>=0){ $$ = strcat($1,(char *)strcat((char *)"//",heldComments[currentDepth])); . . . 绘制说明符号。

我想画的是

Expected image

我正在使用下面的代码

enter image description here

UIBezierPath

感谢任何帮助或指示。

解决方法

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

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

考虑以下情况,抚摸三个路径,一个圆弧和两个三次贝塞尔曲线(加上抚摸贝塞尔曲线的控制点):

enter image description here

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

摆脱令人分心的颜色:

enter image description here

仅供参考,这产生了上述内容:

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,controlPoint2: cp2)

    shapeLayer.path = path.cgPath
}

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