我试图从石英中的椭圆中心绘制径向。
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);
结果:
它不是从椭圆中心发出的线条图,而是随着矩阵的每次变换而移动。为什么中心重置而不是旋转?
答案 0 :(得分: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);
}
这样可以节省每次通过循环时执行三次单独矩阵运算的性能损失。但选择哪一个更清楚你;除非您发现对您的表现产生可衡量的影响,否则始终更喜欢可维护性。