Xcode CGContext addQuadCurve添加箭头

Xcode CGContext addQuadCurve添加箭头,xcode,draw,cgcontext,Xcode,Draw,Cgcontext,如果我用 ctx.moveto:CGPointx:x,y:y ctx.addQuadCurveto:CGPointx:x+dist,y:y,control:CGPointx:x+dist/2,y:y-arcY 我想在曲线的顶部画一个箭头来指示方向。我可以得到箭头的X,我知道在这一点上它将是一个水平箭头。我可以在X值处确定曲线的Y值吗 我并不坚持使用addQuadCurve,事实上addCurve提供了更好的曲线。只需要一个解决方案,我可以得到箭头的Y值并绘制它 点代表控制点,我想在曲线顶部画箭头

如果我用

ctx.moveto:CGPointx:x,y:y ctx.addQuadCurveto:CGPointx:x+dist,y:y,control:CGPointx:x+dist/2,y:y-arcY

我想在曲线的顶部画一个箭头来指示方向。我可以得到箭头的X,我知道在这一点上它将是一个水平箭头。我可以在X值处确定曲线的Y值吗

我并不坚持使用addQuadCurve,事实上addCurve提供了更好的曲线。只需要一个解决方案,我可以得到箭头的Y值并绘制它

点代表控制点,我想在曲线顶部画箭头。我知道X值,但Y值是多少?

似乎没有人对这个问题感兴趣,作为OP,我必须说我不怪他们。然而,即使没有人可能会读到这篇文章,我觉得有义务发布一个解决方案,该解决方案适用于我的这个特定应用程序

我所做的是使用“addEllipse”绘制一个椭圆,然后在椭圆顶部绘制箭头,即y=椭圆的高度,x=椭圆的宽度。我刚刚用“填充”矩形擦除了椭圆的下半部分


这是一个非常具体问题的非常具体的解决方案。

这些类型的曲线只是数学,你可以直接计算数学。既然你说你更喜欢addCurve,那么它的数学模型就是一个三次Bézier。有一篇关于Bézier函数的非常好的文章,我们可以从中获取公式:

关于这个公式需要记住的重要一点是,维度坐标都是独立的。如果要计算曲线的Y坐标,则只需要控制点的Y坐标。理解函数通常从t=0到t=1计算也是很有用的,其中t=0是起点,t=1是终点,t=0.5是中点。请注意,t=0.25不是四分之一点。以恒定速率沿着这条曲线移动有点复杂

那么,在程序员的语言中,这是什么样子的呢

func bezier(t: CGFloat, P0: CGFloat, P1: CGFloat, P2: CGFloat, P3: CGFloat) -> CGFloat {
    return pow(1 - t, 3) * P0
        + 3 * pow(1 - t, 2) * t * P1
        + 3 * (1-t) * pow(t, 2) * P2
        + pow(t, 3) * P3;
}
这不是一个有效的实现。它的目的是尽可能地匹配正式定义,以使其更易于理解。如果您想了解一些加快速度的技巧,请参阅

假设你的第一个点P0在0,0,你的第一个控制点P1在5,5,你的第二个控制点P2在10,5,你的最后一个点P3在10,0,那么沿着曲线t=0.5的中间点是:

bezier(t: 0.5, P0: 0, P1: 5, P2: 5, P3: 0) // 3.75
在许多情况下,您还需要曲线的导数切线斜率,这在同一页上也可用:

你可以用它来计算如何画一条与曲线相切的直线,这在你的例子中是不必要的,因为你知道它是水平的,但它通常是有用的

如果您决定使用四元曲线,则该方程式也可在同一页面上使用,并将以相同的方式使用


贝塞尔曲线没有什么神奇之处。它们只是一个有趣而有用的函数的图,一般可以通过一些一年级代数来理解。如果你研究构建贝塞尔曲线部分,并盯着动画看一会儿,许多神秘可能会消失,取而代之的是对其美丽的敬畏。

@Rod这是一个多么好的答案。这正是我想要的。我更改了代码,以使用您在中间标记处查找Y值的方法。还可以考虑使用你的导数公式在弧的端点以正确的角度绘制箭头。建议任何看到此答案的人忽略它,看看@Rod Napier Response,此方法有效,但与他的方法相比,它既笨拙又丑陋。