iphone – 绘制平滑曲线 – 需要的方法

iphone – 绘制平滑曲线 – 需要的方法,第1张

概述像以前的人都问过,你如何平滑一组点在iOS绘图应用程序WHILE MOVING?我试过UIBezierpaths,但我得到的是锯齿的结束,他们相交,当我只是移动点1,2,3,4 – 2,3,4,5。我听说过样条曲线和所有其他类型。我是新的iPhone编程,不明白如何编程在我的石英绘图应用程序。一个坚实的例子将非常感谢,我已经花了几个星期的圈子,我永远似乎找不到任何iOS代码这个任务。大多数帖子只是 像以前的人都问过,你如何平滑一组点在iOS绘图应用程序WHILE MOVING?我试过UIBezIErpaths,但我得到的是锯齿的结束,他们相交,当我只是移动点1,2,3,4 – 2,4,5。我听说过样条曲线和所有其他类型。我是新的iPhone编程,不明白如何编程在我的石英绘图应用程序。一个坚实的例子将非常感谢,我已经花了几个星期的圈子,我永远似乎找不到任何iOS代码这个任务。大多数帖子只是链接到一个java模拟或wikipedia上的页面曲线拟合,这对我没有什么。我也不想切换到openGL ES。我希望有人能够终于提供代码来回答这个循环的问题。

谢谢,新年快乐!!!

…………………………………………. …………………………………………. …………………………………………. ……………

这是我的代码为UIBezIErPath左边缘交叉///

更新到下面的答案

#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]- (UIBezIErPath*)smoothedpathWithGranularity:(NSInteger)granularity{    NSMutableArray *points = [(NSMutableArray*)[self pointsOrdered] mutablecopy];    if (points.count < 4) return [self bezIErPath];    // Add control points to make the math make sense    [points insertObject:[points objectAtIndex:0] atIndex:0];    [points addobject:[points lastObject]];    UIBezIErPath *smoothedpath = [self bezIErPath];    [smoothedpath removeAllPoints];    [smoothedpath movetoPoint:POINT(0)];    for (NSUInteger index = 1; index < points.count - 2; index++)    {        CGPoint p0 = POINT(index - 1);        CGPoint p1 = POINT(index);        CGPoint p2 = POINT(index + 1);        CGPoint p3 = POINT(index + 2);        // Now add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines        for (int i = 1; i < granularity; i++)        {            float t = (float) i * (1.0f / (float) granularity);            float tt = t * t;            float ttt = tt * t;            CGPoint pi; // intermediate point            pi.x = 0.5 * (2*p1.x+(p2.x-p0.x)*t + (2*p0.x-5*p1.x+4*p2.x-p3.x)*tt + (3*p1.x-p0.x-3*p2.x+p3.x)*ttt);            pi.y = 0.5 * (2*p1.y+(p2.y-p0.y)*t + (2*p0.y-5*p1.y+4*p2.y-p3.y)*tt + (3*p1.y-p0.y-3*p2.y+p3.y)*ttt);            [smoothedpath addlinetoPoint:pi];        }        // Now add p2        [smoothedpath addlinetoPoint:p2];    }    // finish by adding the last point    [smoothedpath addlinetoPoint:POINT(points.count - 1)];    return smoothedpath;}- (PVPoint *)pointAppendingCGPoint:(CGPoint)CGPoint{    PVPoint *newPoint = [[PVPoint alloc] initInsertingIntoManagedobjectContext:[self managedobjectContext]];    [newPoint setCGPoint:CGPoint];    [newPoint setorder:[NSNumber numberWithUnsignedInteger:[[self points] count]]];    [[self mutableSetValueForKey:@"points"] addobject:newPoint];    [(NSMutableArray *)[self pointsOrdered] addobject:newPoint];    [[self bezIErPath] addlinetoPoint:CGPoint];    return [newPoint autorelease];    if ([self bezIErPath] && [pointsOrdered count] > 3)    {        PVPoint *control1 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 2];        PVPoint *control2 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 1];        [bezIErPath movetoPoint:[[pointsOrdered objectAtIndex:[pointsOrdered count] - 3] CGPoint]];        [[self bezIErPath] addCurvetoPoint:CGPoint controlPoint1:[control1 CGPoint] controlPoint2:[control2 CGPoint]];    }}- (BOol)isComplete { return [[self points] count] > 1; }- (UIBezIErPath *)bezIErPath{    if (!bezIErPath)    {        bezIErPath = [UIBezIErPath bezIErPath];        for (NSUInteger p = 0; p < [[self points] count]; p++)        {            if (!p) [bezIErPath movetoPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];            else [bezIErPath addlinetoPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];        }        [bezIErPath retain];    }    return bezIErPath;}- (CGPathref)CGPath{    return [[self bezIErPath] CGPath];}
解决方法 我只是在我正在开展的一个项目中实现类似的东西。我的解决方案是使用Catmull-Rom样条,而不是使用BezIEr样条。这些提供了非常平滑的曲线,通过一组点而不是一个贝塞尔曲线“点”。

// Based on code from Erica Sadun#import "UIBezIErPath+Smoothing.h"voID getPointsFromBezIEr(voID *info,const CGpathelement *element);NSArray *pointsFromBezIErPath(UIBezIErPath *bpath);#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]@implementation UIBezIErPath (Smoothing)// Get points from BezIEr CurvevoID getPointsFromBezIEr(voID *info,const CGpathelement *element) {    NSMutableArray *bezIErPoints = (__brIDge NSMutableArray *)info;        // RetrIEve the path element type and its points    CGpathelementType type = element->type;    CGPoint *points = element->points;    // Add the points if they're available (per type)    if (type != kCGpathelementCloseSubpath)    {        [bezIErPoints addobject:VALUE(0)];        if ((type != kCGpathelementAddlinetoPoint) &&            (type != kCGpathelementMovetoPoint))            [bezIErPoints addobject:VALUE(1)];    }        if (type == kCGpathelementAddCurvetoPoint)        [bezIErPoints addobject:VALUE(2)];}NSArray *pointsFromBezIErPath(UIBezIErPath *bpath){    NSMutableArray *points = [NSMutableArray array];    CGPathApply(bpath.CGPath,(__brIDge voID *)points,getPointsFromBezIEr);    return points;}- (UIBezIErPath*)smoothedpathWithGranularity:(NSInteger)granularity;{    NSMutableArray *points = [pointsFromBezIErPath(self) mutablecopy];    if (points.count < 4) return [self copy];    // Add control points to make the math make sense    [points insertObject:[points objectAtIndex:0] atIndex:0];    [points addobject:[points lastObject]];    UIBezIErPath *smoothedpath = [self copy];    [smoothedpath removeAllPoints];    [smoothedpath movetoPoint:POINT(0)];    for (NSUInteger index = 1; index < points.count - 2; index++)    {        CGPoint p0 = POINT(index - 1);        CGPoint p1 = POINT(index);        CGPoint p2 = POINT(index + 1);        CGPoint p3 = POINT(index + 2);        // Now add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines        for (int i = 1; i < granularity; i++)        {            float t = (float) i * (1.0f / (float) granularity);            float tt = t * t;            float ttt = tt * t;            CGPoint pi; // intermediate point            pi.x = 0.5 * (2*p1.x+(p2.x-p0.x)*t + (2*p0.x-5*p1.x+4*p2.x-p3.x)*tt + (3*p1.x-p0.x-3*p2.x+p3.x)*ttt);            pi.y = 0.5 * (2*p1.y+(p2.y-p0.y)*t + (2*p0.y-5*p1.y+4*p2.y-p3.y)*tt + (3*p1.y-p0.y-3*p2.y+p3.y)*ttt);            [smoothedpath addlinetoPoint:pi];        }        // Now add p2        [smoothedpath addlinetoPoint:p2];    }    // finish by adding the last point    [smoothedpath addlinetoPoint:POINT(points.count - 1)];    return smoothedpath;}@end

原来的Catmull-Rom实现是基于Erica Sadun在她的一本书中的一些代码,我稍微修改它以允许一个完全平滑的曲线。这被实现为UIBezIErPath上的一个类别,并为我做得很好。

总结

以上是内存溢出为你收集整理的iphone – 绘制平滑曲线 – 需要的方法全部内容,希望文章能够帮你解决iphone – 绘制平滑曲线 – 需要的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1087933.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存