在iOS中旋转一条简单的线条

时间:2014-06-02 16:53:36

标签: ios core-graphics ios7.1 bezier

我使用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);

}

它绘制线条,但不会旋转第二条线条。

感谢。

2 个答案:

答案 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:。您可以在构造路径之前或之后执行此操作,但是您应该在遍历/填充路径之前执行此操作,因为此时路径已复制到当前图形上下文中。您应该通过获取当前上下文并将转换应用于此来放弃整个业务;你只是让自己感到困惑。