Draw ellipse with start and end angle in Objective-C

user1331999 picture user1331999 · May 17, 2012 · Viewed 12k times · Source

I am writing an iPad app in which I am rendering XML objects that represent shapes into graphics on the screen. One of the objects I am trying to render is arcs. Essentially these arcs provide me with a bounding rectangle as well as a start and end angle.

Given attributes:

  • x
  • y
  • width
  • height
  • startAngle
  • endAngle

With these values I need to draw the arc (which is essentially part of an ellipse). I can not use the following:

    UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)];
    [UIColor blackColor] setStroke];
    [arc stroke];

because it draws a full ellipse. Basically I need the above but it needs to take into account the start and end angles so only part of the ellipse is displayed. I am thinking this will involve either drawing a cubic Bezier curve or a quadratic Bezier curve. The problem is I have no clue how to calculate the start point, end point, or control points with the information I am given.

Answer

Ken Thomases picture Ken Thomases · May 18, 2012

You can probably achieve what you want by setting up a clip path around the drawing of the ellipse.

CGContextSaveGState(theCGContext);
CGPoint center = CGPointMake(x + width / 2.0, y + height / 2.0);
UIBezierPath* clip = [UIBezierPath bezierPathWithArcCenter:center
                                                    radius:max(width, height)
                                                startAngle:startAngle
                                                  endAngle:endAngle
                                                 clockwise:YES];
[clip addLineToPoint:center];
[clip closePath];
[clip addClip];

UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)];
[[UIColor blackColor] setStroke];
[arc stroke];

CGContextRestoreGState(theCGContext);

The exact radius for the clipping isn't important. It needs to be big enough so it only clips the ellipse at the ends, not through the desired arc.