且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-25 19:12:00

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



简单插值



您可以按设定的间隔简单地对手指位置进行采样,然后使用类似 Catmull-Rom 样条曲线。这比听起来容易,因为您可以轻松地将Catmull-Rom样条曲线转换为一系列三次贝塞尔曲线。



以下是这样的。假设您有四个连续的样本点 P0 P1 P2 P3 ,连接 P1 P2 $ c $的立方贝塞尔曲线c>由以下控制点定义:

  B0 = P1 
B1 = P1 +(P2 - P0) / 6
B3 = P2 +(P1 - P3)/ 6
B4 = P2

只要您的采样点不太密集且非常容易,这应该可以正常工作。唯一的问题可能是样本的开始和结束,因为第一个和最后一个采样点没有在开放曲线中插值。一个常见的解决方法是将您的第一个和最后一个采样点加倍,以便您有足够的点来让曲线通过每个原始样本。



To了解Catmull-Rom曲线的外观,您可以试用这个 Java applet演示Catmull-Rom样条曲线



为样本拟合曲线



更多提前(并且更困难)的方法是对样本点进行最小二乘近似。如果你想试试这个,程序看起来如下:


  1. 收集样本点

  2. 定义NURBS曲线(包括其结矢量)

  3. 建立样本和线性方程组。曲线

  4. 以最小二乘意义解决系统

假设您可以选择合理的NURBS结矢量,这将为您提供一个NURBS曲线,该曲线非常接近您的采样点,最小化样本与曲线之间的平方距离。如果需要,NURBS曲线甚至可以分解为一系列贝塞尔曲线。



如果您决定探索这种方法,那么本书CAGD的曲线和曲面或类似的参考资料将非常有用。在Farin的第5版中,第9.2节专门讨论了这个问题。第7.8节显示了如何使用贝塞尔曲线进行此操作,但您可能需要一条高度曲线才能获得良好的拟合。


like what i want is if i move my finger fast on the iphone screen , then i want like something that it make a proper curve using quartz 2d or opengl es whatever.

i want to draw a path in curve style...... i had seen that GLPaint(OpenglES) example ,but it will not help me alot , considering if your finger movement is fast.....

something like making a smooth curve..... any one have some kind of example please tell me

thanks

Edit: Moved from answer below:

thanks to all.......

but i had tried the bezier curve algo with two control points but problem is first how to calculate the control points whether there is no predefined points....

as i mentioned my movement of finger is fast...... so most of the time i got straight line instead of curve, due to getting less number of touch points.......

now as mark said piecewise fashion, ihad tried it like considering first four touch points and render them on screen , then remove the first point then again go for next four points ex. step 1: 1,2,3,4 step 2: 2,3,4,5 like that where as in that approach i got an overlap , which is not the issue actually , but didn't get smooth curve........

but for fast movement of finger i have to find something else?????

Depending on the number of sample points you are looking at, there are two approaches that I would recommend:

Simple Interpolation

You can simply sample the finger location at set intervals and then interpolate the sample points using something like a Catmull-Rom spline. This is easier than it sounds since you can easily convert a Catmull-Rom spline into a series of cubic Bezier curves.

Here's how. Say you have four consecutive sample points P0, P1, P2 and P3, the cubic Bezier curve that connects P1 to P2 is defined by the following control points:

B0 = P1
B1 = P1 + (P2 - P0)/6
B3 = P2 + (P1 - P3)/6
B4 = P2

This should work well as long as your sample points aren't too dense and it's super easy. The only problem might be at the beginning and end of your samples since the first and last sample point aren't interpolated in an open curve. One common work-around is to double-up your first and last sample point so that you have enough points for the curve to pass through each of the original samples.

To get an idea of how Catmull-Rom curves look, you can try out this Java applet demonstrating Catmull-Rom splines.

Fit a curve to your samples

A more advance (and more difficult) approach would be to do a Least Squares approximation to your sample points. If you want try this, the procedure looks something like the following:

  1. Collect sample points
  2. Define a NURBS curve (including its knot vector)
  3. Set up a system of linear equations for the samples & curve
  4. Solve the system in the Least Squares sense

Assuming you can pick a reasonable NURBS knot vector, this will give you a NURBS curve that closely approximates your sample points, minimizing the squared distance between the samples and your curve. The NURBS curve can even be decomposed into a series of Bezier curves if needed.

If you decide to explore this approach, then the book "Curves and Surfaces for CAGD" by Gerald Farin, or a similar reference, would be very helpful. In the 5th edition of Farin's book, section 9.2 deals specifically with this problem. Section 7.8 shows how to do this with a Bezier curve, but you'd probably need a high-degree curve to get a good fit.