如何追踪触摸手指的移动以绘制平滑曲线?

12
我想要的是,如果我在iPhone屏幕上快速移动手指,那么我希望能够用Quartz 2D或OpenGL ES等技术创建一个合适的曲线路径。
我想以曲线样式绘制路径...... 我看过GLPaint(OpenglES)示例,但它对我没有太大帮助,考虑到您的手指移动很快时......
我需要创建平滑的曲线路径...... 如果有任何例子,请告诉我。
谢谢。
编辑:由下面的答案移动:
感谢大家.......
但是,我尝试了具有两个控制点的Bezier曲线算法,但问题在于如何计算控制点,而没有预定义的点....。
就像我提到的那样,我的手指移动速度很快......所以大多数时间我得到的是直线而不是曲线,因为触摸点数量较少.......
现在,正如马克所说的分段方式,我已经尝试了这种方式,例如考虑前四个触摸点并将它们呈现在屏幕上,然后删除第一个点,再转向下一个四个点,例如步骤1:1,2,3,4步骤2:2,3,4,5,依此类推,在这种方法中,我得到了重叠,这实际上不是问题,但没有得到平滑的曲线......
但是对于手指的快速移动,我需要找到其他方法吗?

1
我不是iPhone开发者,但你可能需要每20-50毫秒获取触摸位置,然后从所有这些点中选择10个以上,并使用它来计算曲线的理想路径。(由于缺乏真正的知识而发表的评论) - Alex S
你可能想要了解样条函数插值,可以参考http://en.wikipedia.org/wiki/Spline_interpolation。 - Nixuz
3个回答

10

根据您所查看的采样点数,我建议有两种方法:

简单插值

您可以在设置的间隔内简单地采样手指位置,然后使用类似于卡特穆尔-罗姆样条进行插值。这比听起来容易,因为您可以将卡特穆尔-罗姆样条轻松转换成一系列立方贝塞尔曲线。

以下是如何操作的步骤。假设你有四个连续的采样点 P0, P1, P2P3,连接 P1P2 的立方贝塞尔曲线由以下控制点定义:

B0 = P1
B1 = P1 + (P2 - P0)/6
B3 = P2 + (P1 - P3)/6
B4 = P2
只要您的采样点不是太密集,这个方法应该能很好地工作,并且非常容易。唯一的问题可能在于样本开头和结尾的部分,因为在开放曲线中没有插值第一个和最后一个采样点。一个常见的解决方法是复制你的第一个和最后一个采样点,这样你就有足够的点使得曲线能够通过每个原始采样点。
如果想了解Catmull-Rom曲线的外观,可以试用这个演示Catmull-Rom样条的Java小程序
拟合曲线到你的样本
更高级(也更困难)的方法是对你的样本点进行最小二乘逼近。如果您想要尝试这个方法,则过程大致如下:
1. 收集样本点 2. 定义NURBS曲线(包括其结点向量) 3. 为样本和曲线设置一个线性方程组 4. 最小二乘意义下解决系统
假设你可以选择一个合理的NURBS结点向量,这将给你一个NURBS曲线,它密切逼近你的样本点,最小化样本与曲线之间的平方距离。 NURBS曲线甚至可以分解成一系列的Bezier曲线,如果需要的话。
如果您决定尝试这种方法,则Gerald Farin的"Curves and Surfaces for CAGD"或类似参考资料将非常有帮助。在Farin的书的第5版中,第9.2节专门讨论了这个问题。第7.8节展示了如何使用Bezier曲线进行这个问题,但你可能需要一个高阶曲线才能得到良好的拟合。

3
Naaff提供了NURBS技术的很好的概述。不幸的是,我认为在iPhone上即时生成平滑的贝塞尔曲线可能太过于困难。我编写绘图应用程序,每秒获取大量的touchesMoved事件本来就很具有挑战性。您真的需要优化您的绘图代码,才能在记录单个点时获得良好的性能-更不用说构建贝塞尔路径了。
如果您最终选择使用贝塞尔或NURBS曲线表示法-您可能必须等待用户完成触摸屏幕后再计算平滑路径。连续进行数学计算,而用户移动手指时重新绘制整个重新计算的路径(使用Quartz)将无法获得足够高的数据收集速率以做任何有用的事情...
祝好运!

那么你会推荐什么呢?这里缺乏答案,所以评为-1分。(但我猜加入一些有用的背景信息应该算+1分,所以净得分为0分。) - livingtech

1

按照Shadow的建议做一些事情。以一定的频率获取触摸位置,然后用Bézier曲线绘制出来。这就是在像Illustrator这样的程序中使用鼠标(或平板电脑)绘制路径的方式。


1
补充David的评论,你可能想做的是从笔画的一端开始,以分段方式逐步构建拟合数据点的样条曲线。 - Mark Bessey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接