我使用bezier路径绘制了两行,它们如下所示:
________________
________________
我想要完成的是旋转第二行。但我似乎无法做对。 这是我到目前为止所做的。
- (void)drawRect:(CGRect)rect
{
//Path #1
UIBezierPath *p1 = [UIBezierPath bezierPath];
[p1 moveToPoint:CGPointMake(100.0, 100.0)];
[p1 addLineToPoint:CGPointMake(250.0, 100.0)];
[p1 closePath];
p1.lineWidth = 15;
[[UIColor greenColor]setStroke];
[[UIColor redColor]setFill];
//draw the path
[p1 fill];
[p1 stroke];
//Path #2
UIBezierPath *p2 = [UIBezierPath bezierPath];
CGContextRef context = UIGraphicsGetCurrentContext();
[p2 moveToPoint:CGPointMake(100.0, 200.0)];
[p2 addLineToPoint:CGPointMake(250.0, 200.0)];
[p2 closePath];
p2.lineWidth = 15;
[[UIColor blueColor]setStroke];
[[UIColor yellowColor]setFill];
[p2 fill];
[p2 stroke];
CGContextRotateCTM(context, M_PI);
}
它绘制线条,但不会旋转第二条线条。
感谢。
答案 0 :(得分:3)
要了解你在做什么,试试这个。在模拟器上切出一张纸大小的视图。注释掉你的旋转线,运行应用程序,并跟踪它在未旋转位置显示的行。现在,取消注释该行(但旋转M_PI / 4.0)并再次运行应用程序 - 您应该看到屏幕左侧部分偏离45度角的线条。现在,将纸张的左上角固定在模拟器视图的左上角,顺时针旋转纸张45度 - 跟踪线现在应该与屏幕上的线重叠。这是你在旋转时所做的事情(如果你想要90度旋转而不是M_PI,你想使用M_PI / 2.0)。
要让线从左边缘旋转,你需要翻译视图但是它的x和y坐标,然后进行旋转,然后翻译回来,
//Path #2
UIBezierPath *p2 = [UIBezierPath bezierPath];
CGContextRef context = UIGraphicsGetCurrentContext();
[p2 moveToPoint:CGPointMake(100.0, 200.0)];
[p2 addLineToPoint:CGPointMake(250.0, 200.0)];
[p2 closePath];
p2.lineWidth = 15;
[[UIColor blueColor]setStroke];
[[UIColor yellowColor]setFill];
[p2 fill];
CGContextTranslateCTM(context, 100, 200);
CGContextRotateCTM(context, M_PI/2.0);
CGContextTranslateCTM(context, -100, -200);
[p2 stroke];
正如马特在他的回答中所说,你可以将转移直接应用于贝塞尔曲线而不是坐标空间。我认为这可能是一种更好的方法,在概念上更容易理解。在我上面给出的纸张示例中,您会注意到唯一不会改变其旋转位置的点是{0,0}。因此,如果要旋转贝塞尔曲线路径,请将其平移,使您想要保持固定的点为{0,0},旋转它,然后平移回来。从功能上来说,这只是意味着你首先用x和y坐标的负数进行翻译(而不是用我原来的答案进行正面翻译)。所以,对于你的例子,那就是,
//Path #2
UIBezierPath *p2 = [UIBezierPath bezierPath];
[p2 moveToPoint:CGPointMake(100, 200)];
[p2 addLineToPoint:CGPointMake(250.0, 200)];
p2.lineWidth = 8;
[[UIColor blueColor]setStroke];
[p2 applyTransform:CGAffineTransformMakeTranslation(-100, -200)];
[p2 applyTransform:CGAffineTransformMakeRotation(M_PI/2)];
[p2 applyTransform:CGAffineTransformMakeTranslation(100, 200)];
[p2 stroke];
另请注意,您的填充不起作用,因为一条线(作为数学概念)没有内部,所以没有任何东西可以填充 - 中风的宽度不会影响它。如果你想要填充,那么你应该绘制一个矩形而不是一条线(不需要closePath调用,因为没有什么可以用线关闭)。
答案 1 :(得分:1)
将变换应用于贝塞尔曲线路径的方法是使用applyTransform:
。您可以在构造路径之前或之后执行此操作,但是您应该在遍历/填充路径之前执行此操作,因为此时路径已复制到当前图形上下文中。您应该通过获取当前上下文并将转换应用于此来放弃整个业务;你只是让自己感到困惑。