Undestanding UIBezierPath弯曲机制,controlPoint和曲线点

Eil*_*lon 4 graphics ios uibezierpath swift

我正在尝试使用简单的抛物线形状UIBezierPath.我有一个maxPoint和一个boundingRect我基于抛物线的宽度和伸展.
下面是我做得出抛物线(我画在容器视图中的抛物线,该功能rectcontainer.bounds):

func addParabolaWithMax(maxPoint: CGPoint, inRect boundingRect: CGRect) {
    let path = UIBezierPath()

    let p1 = CGPointMake(1, CGRectGetMaxY(boundingRect)-1)
    let p3 = CGPointMake(CGRectGetMaxX(boundingRect)-1, CGRectGetMaxY(boundingRect)-1)

    path.moveToPoint(p1)
    path.addQuadCurveToPoint(p3, controlPoint: maxPoint)

    // Drawing code
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我希望maxPoint我在函数中发送的是抛物线本身的实际极端点.例如,如果我发送(CGRectGetMidX(container.bounds), 0),最大点应该在最顶端的中心.但是在使用此特定点的函数时,结果如下:

在此输入图像描述

那么这条道路究竟是什么呢?或者换句话说,我怎样才能从controlPoint我需要的实际最大点到达?我已经尝试根据y值的高度添加和减去值中的不同值boundingRect,但我找不到正确的组合,因为在具有不同y值的不同点中它表现不同.似乎有某种乘数被添加,我该如何解决?

Rob*_*ier 7

对于may应用程序,adam.wulf的解决方案很好,但它实际上并没有创建一个抛物线.要创建抛物线,我们需要计算给定二次曲线中点的控制点.Bézier路径只是数学; 我们可以很容易地计算出来.我们只需要反转Bézier函数并在t = 0.5时求解它.

0.5(中点)处的Bézier解是通过三个给定点绘制二次贝塞尔曲线得出的.

2*Pc - P0/2 - P2/2
Run Code Online (Sandbox Code Playgroud)

哪里Pc是我们想通过和点P0P2是终点.

(在其他点计算Bézier不是很直观.t = 0.25时的值不是"沿路径的四分之一."但幸运的是,对于我们的目的,t = 0.5与我们对"中点"的直觉非常吻合"在二次方上.)

鉴于我们的解决方案,我们可以编写代码.原谅Swift 3的翻译; 我的Xcode 7.3副本对iOS游乐场不是很满意,但它应该很容易转换为2.2.

func addParabolaWithMax(maxPoint: CGPoint, inRect boundingRect: CGRect) -> UIBezierPath {

    func halfPoint1D(p0: CGFloat, p2: CGFloat, control: CGFloat) -> CGFloat {
        return 2 * control - p0 / 2 - p2 / 2
    }

    let path = UIBezierPath()

    let p0 = CGPoint(x: 0, y: boundingRect.maxY)
    let p2 = CGPoint(x: boundingRect.maxX, y: boundingRect.maxY)

    let p1 = CGPoint(x: halfPoint1D(p0: p0.x, p2: p2.x, control: maxPoint.x),
                     y: halfPoint1D(p0: p0.y, p2: p2.y, control: maxPoint.y))

    path.move(to: p0)
    path.addQuadCurve(to: p2, controlPoint: p1)
    return path
}
Run Code Online (Sandbox Code Playgroud)

halfPoint1D功能是我们解决方案的一维实现.对于我们的二维CGPoint,我们只需要调用它两次.

如果我只推荐一种资源来理解Bézier曲线,它可能就是维基百科的"构造Bézier曲线"部分.研究显示曲线如何形成的小动画,我发现非常具有启发性."特定案例"部分也很有用.为了深入探讨这个主题(我建议所有开发人员都熟悉这个主题),我喜欢BézierCurves的A Primer.可以浏览它,只需阅读您感兴趣的部分.但是,对这组函数的基本理解将大大有助于消除绘制Core Graphics中的魔力并使UIBezierPath成为工具而不是黑盒子.