我使用方法CGPathAddQuadCurveToPoint
制作了四条曲线路径。我完美地完成了这条道路。但是,我想知道参与路径的所有坐标点。
有没有办法检索路径中的所有坐标点?
如果没有,你有任何其他方法可以用数学方法检索曲线中的所有点。
提前致谢, Vamshi
答案 0 :(得分: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
答案 1 :(得分: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();
答案 2 :(得分:1)
如果您想处理路径的moveto,lineto和curveto元素,请使用CGPathApply。您将此指针传递给程序中的函数,并且每个元素都会调用该函数一次。
不幸的是,没有办法像AppKit的NSBezierPath那样只询问每个元素。功能是唯一的方法。
如果你想确定路径相交的每个像素,那太糟糕了 - 这是不切实际的,我甚至无法想到你为什么要这些信息。某些上下文(例如PDF contexts)甚至没有像素;在这些情况下,任何涉及像素的问题都是不合理的。
答案 3 :(得分:0)
二次曲线就是 - 曲线。它不可能得到所有点的列表,因为它有无限多的点,而且它不是一个简单的线段。
有关可用于查询CGPath
对象的函数列表,请参阅Getting Information about Quartz Paths。不幸的是,看起来您将获得的最有用的信息是CGPathContainsPoint()
,它只会告诉您某个点是否包含在路径区域内。
答案 4 :(得分:0)
如果没有,你还有其他解决办法以数学方式检索曲线中的所有点。
你需要什么,比如你想解决什么问题?如果要交叉两条曲线,可以用数学方法完成。只需将两个曲线方程设置为彼此相等并求解未知数。
答案 5 :(得分:0)
我猜你是在追求与Java2D FlatteningPathIterator类相同的东西。例如,Java2D的path.getPathIterator(null, 1.0)
只返回'lineTo'段的迭代器,即使原始路径有curveTo和quadTo,double参数控制'flatness',这使您可以轻松计算曲线上的任何点。
我在Cocoa中寻找相同的东西,但一无所获。如果您找到解决方案,请告诉我。
可以移植(例如http://sourceforge.net/projects/curves/)周围的曲线实现,但是如果你不使用与Cocoa相同的算法,那么你的插值和描边的NSBezierPath / CGPath之间可能存在错误。