Objective C Bezier Curve ReShaping

时间:2012-02-13 15:35:36

标签: iphone objective-c ios ipad

我希望能够通过触摸并拖动它来重新定位和重塑Core Graphics中绘制的三次贝塞尔曲线。我可以绘制基本形状,我可以使用触摸和拖动来移动形状的整体,但这不是我想要做的。

我想要的是能够移动和重塑贝塞尔曲线,就好像它是一块躺在桌子上的绳子被我的手指拉动。即接触贝塞尔曲线的一部分并将其拉向一个方向以改变整体曲线的形状。

有谁知道怎么做?任何帮助都会非常受欢迎。

提前致谢

2 个答案:

答案 0 :(得分:5)

绘制控制点并允许用户拖动它们相当容易。遗憾的是,曲线并未通过所有控制点,因此体验与您的建议不完全相符。

要做你所建议的,你首先要回答的问题是“用户是否触摸了曲线?”这与问题“是曲线的某个距离内的给定点”相同。这不是一个微不足道的问题,但可以计算出来。可能最简单的方法是沿曲线计算X点(X足够高以提供合理的精度),并检查每个点的距离。原则上,您也可以采用距离方程的导数并将其求解为零,但这需要迭代。根据我的经验,您可以足够快地计算所需的1000个左右的距离(即使在iPad 1上),这可能不值得额外的复杂性。

一旦发现用户实际上正在触摸曲线,就很容易找出最接近的控制点。在这一点上,最重要的是决定如何应对它。一些选择:

  • 沿用户移动的方向移动最近的控制点。您可能需要进行多次计算,直到找到通过触摸点的新曲线。这是最简单的方法,可能就是我开始的地方。
  • 您可以在触摸点处细分曲线并移动新创建的端点。 (请参阅De Casteljau's算法。)除非您调整其他控制点以创建匹配的斜率,否则这将产生尖角。这允许更多任意曲线,但是可能变得非常难以知道用户真正想要的是什么。你几乎肯定也需要应用Ramer-Douglas-Peucker来保持你的曲线数量不会爆炸。

我目前对Objective-C中的Bézier曲线问题很感兴趣。您可能对我的first post on the subject感兴趣。我在GitHub示例代码的iOS:PTL上可以找到我在此领域的初步工作。希望本周我还有另一篇文章。你的特殊问题很有意思,所以我可以看看我能围绕它做些什么。

答案 1 :(得分:5)

嗯,你确定你需要完全贝塞尔曲线吗?或者你只需​​要路径上的一些平滑曲线?您需要的行为很容易使用其他曲线类型实现:Cardinal或它的子类型,如Catmull-Rom样条曲线。

红衣主教样条优于贝齐尔的好处实际上是样条曲线总是通过控制点,即从路径添加,移动或擦除一个点不会影响其他点,曲线看起来仍然很好。此外,数学更简单(计算速度更快)。

CoreGraphics中没有显示基数样条曲线,但您可以绘制一条近似曲线的多边形曲线,其中有一些小的 t 步骤。其余的(找出触摸是否在曲线上等)在Rob的回答中有解释,我只能补充一点,曲线的多线近似几乎解决了这个任务,因为你需要的只是找到一个段与触摸点的距离最短。