【问题标题】:How can I move a CGPath without creating a new one如何在不创建新路径的情况下移动 CGPath
【发布时间】:2010-02-12 21:04:07
【问题描述】:

我正在创建一个CGPath 来在我的游戏中定义一个区域,如下所示:

CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

我知道这只是一个正方形,我可以使用另一个 CGRect,但我希望实际创建的路径实际上并不是一个矩形(我现在只是在测试)。然后简单地检测触摸区域:

if (CGPathContainsPoint(myPath, nil, location, YES))

这一切都很好,问题是CGPath 可能每秒移动多达 40 次。我怎样才能移动它而不必创建一个新的?我知道我可以做这样的事情来“移动”它:

center.y += x;
CGPathRelease(myPath);
myPath = CGPathCreateMutable();
CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

但是我必须以每秒 40 次的速度发布和创建新路径,我认为这可能会降低性能;这是真的吗?

我希望能够移动它,就像我当前移动一些 CGRects 一样,只需将原点设置为不同的值,CGPath 可以做到这一点吗?

谢谢。

编辑:我忘了提到我没有 GraphicsContext,因为我没有在 UIView 上绘图。

【问题讨论】:

    标签: iphone core-graphics cgpath


    【解决方案1】:

    对 CGPath 应用变换并针对点进行测试,相当于对点应用变换。

    因此,您可以使用

    CGPoint adjusted_point = CGPointMake(location.x - center.x, location.y - center.y);
    if (CGPathContainsPoint(myPath, NULL, adjusted_point, YES)) 
    

    但是CGPathContainsPoint 已经有一个CGAffineTransform 参数(你有NULL-ed),所以你也可以使用

    CGAffineTransform transf = CGAffineTransformMakeTranslation(-center.x, -center.y);
    if (CGPathContainsPoint(myPath, &transf, location, YES)) 
    

    如果您正在绘图,您可以直接在绘图代码中更改 CTM,而不是更改路径。

    CGContextSaveGState(c);
    CGContextTranslateCTM(c, center.x, center.y);
    // draw your path
    CGContextRestoreGState(c);
    

    如果您需要性能,请使用CAShapeLayer

    【讨论】:

    • 不会移动整个图形上下文而不仅仅是路径吗?另外我忘了提到我没有图形上下文,因为我没有在 UIView 上绘图
    • 谢谢你,这对我有很大帮助!。不必移动我所有的多边形,我可以翻译我的观点,我之前应该考虑过这一点。还有一个性能问题,创建新的 cgpoint 或使用 CGAffine 变换哪个更好?
    • 我认为创建一个新的 CGPoint 更快,因为应用转换涉及额外的乘法。
    • CGAffineTransformMakeTranslation 由于某种原因没有被应用到该点...
    【解决方案2】:

    @KennyTM 的回答非常适合 OP,但问题仍然存在:

    如何在不创建新路径的情况下移动 CGPath?

    嗯,两行代码帮了我大忙:

    UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:cgPath];
    [path applyTransform:CGAffineTransformMakeTranslation(2.f, 0.f)];
    

    【讨论】:

    • 还有:CGPathCreateCopyByTransformingPath(CGPathRef path,const CGAffineTransform *transform);
    • @Antoine 谢谢,但这仍然会创建一个新的 CGPath,这是 OP 试图避免的。如果问题更好,代码更简洁,那么您的答案就是完美的。
    • 是的,我知道。不幸的是,OP 正在寻找的是 OS X NSBezierPath 方法setAssociatedPoints:atIndex: 您可以使用此方法快速更改与路径关联的点,而无需重新创建路径。我希望将来 UIBezierPath 的行为更像 NSBezierPath。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2012-08-27
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多