【问题标题】:Draw Radials from center of ellipse in Quartz在 Quartz 中从椭圆的中心绘制径向线
【发布时间】:2011-06-30 04:09:58
【问题描述】:

我正在尝试从石英椭圆的中心绘制径向线。

CGContextSetRGBStrokeColor(ctx, 0.0, 1.0, 1.0, 1.0); //cyan stroke
CGContextSetLineWidth(ctx, 2.0);
CGContextFillEllipseInRect(ctx, oRect);

CGContextSaveGState(ctx);        

CGPoint center = CGPointMake(CGRectGetMidX(oRect), CGRectGetMidY(oRect));
CGFloat maxX = CGRectGetMaxX(oRect);

for(int i = 0; i < 5; i++) {
    CGContextBeginPath(ctx);        
    CGContextMoveToPoint(ctx, maxX, center.y);
    CGContextAddLineToPoint(ctx, center.x, center.y);
    CGContextClosePath(ctx);
    CGContextStrokePath(ctx);
    CGContextRotateCTM(ctx, degreesToRadians(5.0));
}


CGContextRestoreGState(ctx);

结果:

不是从椭圆中心发出的线条图,而是随着矩阵的每次变换而移动。为什么中心是重置而不是旋转?

【问题讨论】:

    标签: iphone objective-c ipad quartz-2d cgcontext


    【解决方案1】:

    很简单,这是因为CGContextRotateCTM(ctx, degreesToRadians(5.0)); 调用应用了一个围绕坐标系原点的旋转矩阵。在这种情况下,原点似乎位于视图的左上角。整个东西都围绕着左上角旋转,而不是围绕着你的视野中点。

    如果您想围绕视图中心旋转,您需要先移动坐标系。最简单的方法可能只是应用平移将其移动到中心,应用旋转,然后应用另一个平移将其移回角落。它最终会是这样的:

    ///...
    CGPoint center = CGPointMake(CGRectGetMidX(oRect), CGRectGetMidY(oRect));
    CGFloat maxX = CGRectGetMaxX(oRect);
    
    for(int i = 0; i < 5; i++) {
        CGContextBeginPath(ctx);        
        CGContextMoveToPoint(ctx, maxX, center.y);
        CGContextAddLineToPoint(ctx, center.x, center.y);
        CGContextClosePath(ctx);
        CGContextStrokePath(ctx);
        CGContextTranslateCTM(ctx, center.x, center.y); // Note
        CGContextRotateCTM(ctx, degreesToRadians(5.0));
        CGContextTranslateCTM(ctx, -center.x, -center.y); // Note
    }
    

    当然,您可以将整个 translate-rotate-translate 操作合并为一个 CGAffineTransform,如下所示:

    // Outside the loop
    CGAffineTransform transform = CGAffineTransformMakeTranslation(center.x, center.y);
    transform = CGAffineTransformRotate(transform, degreesToRadians(5.0));
    transform = CGAffineTransformTranslate(transform, -center.x, -center.y);
    
    for(int i = 0; i < 5; i++) {
        // ...
        CGContextConcatCTM(ctx, transform);
    }
    

    这将为您节省执行三个单独的矩阵运算的性能损失,每个运算都通过循环。但是选择对你来说更清楚的那个;除非您看到对您的性能有可衡量的影响,否则总是更喜欢可维护性。

    【讨论】:

    • 好点。我意识到旋转发生在左上角的原点周围。但是,直到我撤消了翻译调用,您的第一个示例才起作用。第一个可能是积极的 center.x & center.y 而不是消极的。一旦我反转了负/正操作数,它就可以正常工作了。
    • 啊,很高兴知道。我不记得它是在翻译原点还是绘图调用,尽管我猜它最终是同一回事。无论如何,我会解决它。
    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多