18

我使用该方法制作了一条四边形曲线路径CGPathAddQuadCurveToPoint。我得到了完美的路径。但是,我想知道参与路径的所有坐标点。

有没有办法检索路径中的所有坐标点?

如果没有,您是否有任何其他解决方案可以在数学上检索曲线中的所有点。

在此先感谢, Vamshi

4

6 回答 6

14

您可以使用三次贝塞尔曲线的 wykobi C++ 库例程来执行此操作。Wykobi 的库也支持二次贝塞尔曲线。

当然,正如有人指出的那样,您并不想要所有的点(尽管并非不可能,但这只会花费无限的时间:)。Wykobi 可以轻松获得一定数量的点 - 如果您的起点、c1、c2 和终点(其中 c1、c2 是控制点)与提供给 CGContextAddCurveToPoint 的点完全相同,那么这些点将完美地位于在核心图形绘制的线上——这样你就可以在路径上的几个点上画一个图案。

请参阅: http: //www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi

另外,在我开始使用 wykobi 之后,我听说有一个类似的,甚至可能更好的库,它是 Boost 的一部分,但还没有检查出来。

我创建了一个 C++ 类 WPoint 作为 wykobi 点和 CGPoints 之间的桥梁(C++ 很有趣!)。这是一些代码(没有 WPoint,但您可以想象它与 CGPoint 的布局完全相同,因此如果您进行正确的转换,您可以轻松转换。

        NSMutableArray* result = [[NSMutableArray alloc] init];
        wykobi::cubic_bezier<CGFloat,2> bezier;
        bezier[0] = (WPoint)p1;  // start point, in CG we did a CGMoveToPoint
        bezier[1] = (WPoint)b1i; // control 1
        bezier[2] = (WPoint)b2i; // control 2
        bezier[3] = (WPoint)p2;  // end point

        std::vector<WPoint> point_list;
        int numPoints = p2.dist(p3) * pointDensity;
        // *** here's the magic ***
        wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints);

        for (int i=0; i<numPoints; i++) {
            CGPoint p = (CGPoint)(point_list[i]);
            [result addObject:[NSValue valueWithCGPoint:p]];
        }

// result has your points!

这是 Boost 几何库的链接:http: //www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html

于 2012-07-27T03:22:31.353 回答
2

使用 CGContextSetLineDash

此函数的目的是创建一条虚线,但您可以使用它来获得更小的线段。每个段的起点都可以视为点。

CGSize bbSize = CGPathGetBoundingBox(path).size;
UIGraphicsBeginImageContext(bbSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.0);
CGContextAddPath(ctx, path);
CGContextSetLineDash(ctx, phase, lengths, count);
CGContextReplacePathWithStrokedPath(ctx);
result = CGContextCopyPath(ctx);
UIGraphicsEndImageContext();
于 2013-12-18T05:21:03.443 回答
1

If you want to work on the moveto, lineto, and curveto elements of the path, use CGPathApply. You pass this a pointer to a function in your program, and it calls that function once per element of the path.

Unfortunately, there's no way to just ask for each element like there is with AppKit's NSBezierPath. The function is the only way.

If you want to determine every pixel intersected by the path, too bad—that's not practical, and I can't even think of why you'd want that information. Some contexts, such as PDF contexts, don't even have pixels; in those cases, any question involving pixels is a non sequitur.

于 2009-05-08T19:15:37.957 回答
0

我猜您正在寻找与 Java2D FlatteningPathIterator 类等效的东西。例如path.getPathIterator(null, 1.0),即使原始路径具有curveTo 和quadTo,Java2D 也会返回仅包含“lineTo”段的迭代器,双参数控制“平坦度”,为您提供一种计算曲线上任何点的简单方法。我在 Cocoa 中寻找同样的东西,但什么也没找到。如果您找到解决方案,请告诉我。周围有曲线实现(例如http://sourceforge.net/projects/curves/)可以移植,但总是存在风险,如果您不使用与 Cocoa 相同的算法,那么您的插值之间可能会出现错误和描边的 NSBezierPath/CGPath。

于 2009-06-12T07:05:39.447 回答
0

二次曲线就是这样——一条曲线。不可能得到上面所有点的列表,因为有无限多的点,而且它不是一个简单的线段。

有关可用于查询对象的函数列表,请参阅获取有关 Quartz 路径的信息。CGPath不幸的是,您将获得的最有用的信息似乎是 with CGPathContainsPoint(),它只会告诉您给定点是否包含在路径区域内。

于 2009-05-08T18:19:51.977 回答
0

If not do u have any other solution for retrieving all the points in a curve mathematically.

What do you need them for, i.e. what problem are you trying to solve? If it is to intersect two curves, you can do this mathematically. Just set the two curve equations equal to each other and solve for the unknown.

于 2009-05-08T19:58:16.310 回答