在UIBezierCurve上计算细粒度的点列表

时间:2014-04-30 17:56:21

标签: ios objective-c algorithm math uibezierpath

所以我遇到了一个相当有趣的,可能与苹果实施Bezier曲线有关的高度数学问题。

所以为了切入追逐,我有一个UIBezierCurve。我绘制了3个点来生成曲线。左点,控制点和右点。这是一个例子:

UIBezierPath *bezierCurve = [UIBezierPath bezierPath];
[bezierCurve moveToPoint:leftCorner];
[bezierCurve addQuadCurveToPoint:rightCorner controlPoint:controlPoint];

其中leftCorner,rightCorner和controlPoint都是CGPoints。它几乎是一个颠倒的抛物线(我通常使用的值,虽然这可能无关紧要,它的抛物线以某种方式通过垂直线测试)。像这样:https://www.wolframalpha.com/input/?i=graph+of+y+%3D+-x%5E2

现在我要做的是沿着这个bezierCurve收集一个点列表。不仅仅是我用来创造它的3个点。例如,我想有一个细粒度的列表,其中可能有数百个点沿着曲线均匀分布。

我是如何解决这个问题的:爬山算法。我的实现基本上是从曲线的左边开始(左角)并沿着曲线走,直到我到达右角。每次我向右走1个单位时,我会尝试使用以下方式拥抱曲线:

- (BOOL)containsPoint:(CGPoint)point

这相当不错,我得到了曲线上几百个点的列表。然而问题是它们肯定不是等间隔的(等距离可能是我在这里寻找的术语)。在曲线的斜率相对平坦的情况下,我得到许多点,并且它们相当均匀地间隔开。当斜率很大时,与这些区域中线的长度相比,我获得的点数非常少。有时在非常陡峭的区域(当应该有很多区域)时只有一两个点。

我认为我应该解决这个问题的方法是采用我的爬山算法(水平行走,沿着x轴弯曲并沿曲线行走)并垂直添加第二道(沿y轴行走,拥抱曲线)。然后通过按x值排序合并这两组点,然后在每个x值中按y值排序。

但是我认为必须有一种更容易,更简单的方法来做到这一点。在Android上你所要做的就是类似于UIBezierCurve(android的“Path”类)的类是:

for (int i = 0; i < pathMeasure.getLength(); i++) 
{
    float[] point = new float[2];
    float[] tangent = new float[2];

    boolean success = pathMeasure.getPosTan(i, point, tangent);

    if (success) 
    {
            curvePoints.add(new Point((int)point[0], (int)point[1]));
    }
}

最后,我基本上有一个等距列表(curvePoints)。 PathMeasure是适用于android的Path的类(它们都是内置的Android类)。我希望有一些类似于PathMeasure的东西,可以轻松地在UIBezierCurve上获得等距点(细粒度粒度)的列表,并避免在手动完成所有这些操作的过程中。有什么我想念的吗?

谢谢!

0 个答案:

没有答案