When drawing an arc using CGContextAddArcToPoint(), what does (x1,y1) and (x2,y2) mean? When drawing an arc using CGContextAddArcToPoint(), what does (x1,y1) and (x2,y2) mean? ios ios

When drawing an arc using CGContextAddArcToPoint(), what does (x1,y1) and (x2,y2) mean?


AddArcToPoint works like this:

ArcToPoint Diagram

where P1 is the point the path is currently at, r is the radius given to the function, and the red line is the line that addArcToPoint will add to the current path. It won't continue to the second point at x2, y2; it will stop at the end of the arc.

I have a blog post about this here.


http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextAddArcToPoint

x1: The x-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).

y1: The y-value, in user space coordinates, for the end point of the first tangent line. The first tangent line is drawn from the current point to (x1,y1).

x2: The x-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).

y2: The y-value, in user space coordinates, for the end point of the second tangent line. The second tangent line is drawn from (x1,y1) to (x2,y2).


Here's code I just built to solve this, approaching it from the center-of-circle perspective, with declarations and sample values:

CGPoint arcCenter = CGPointMake(30,20);float arcLengthRad = M_PI_4; // Whatever, the full span of the arc in radiansfloat radius = 10;float arcCenterRad = M_PI_2; // the angle of the center of the arc, in radiansfloat arcP1hyp = 1/cos(arcLengthRad/2) * radius;float arcP1x = arcCenter.x + cosf(arcCenterRad)*arcP1hyp;float arcP1y = arcCenter.y + sinf(arcCenterRad)*arcP1hyp;float arcP2tx = arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius;float arcP2ty = arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius;float arcP2x = (arcP1x - arcP2tx)*-1 + arcP2tx;float arcP2y = (arcP1y - arcP2ty)*-1 + arcP2ty;CGContextAddArcToPoint(context,                        arcP1x,                        arcP1y,                       arcP2x,                        arcP2y,                       radius);

So the above code should produce a small, 45-degree angle arc at the top of a circle.


Edited:In response to a comment received, the super-concise code listed above is shown below, with comments and wrapped in a method (plus a minor adjustment to the arcP2 calculation)

/*EOTContext:addArcWithCenter:arcLength:radius:arcMiddlePointAngle:Use this method for building a circle with breaks at certain points, for example to use other CGContext methods to draw notches in the circle, or protruding points like gear teeth.This method builds up the values to use in CGContextAddArcToPoint(), which are the x and y coordinates of two points.  First  added to the current point in context, form two lines that are the tangents of the entry and exit angles of the arc.This method's arguments define the length of the arc in radians, and the position of start and end using the angle centerpoint of the arc.  This is useful when drawing a certain defined amount of gear teeth, rotating around the circle.It is beyond this method's scope to maintain or calculate the centerpoint relative to an arbitrary current point in the context, because this is primarily used for drawing a gear/notch circle.*/-(void)EOTContext:(CGContext*)context addArcWithCenter:(CGPoint)arcCenter arcLength:(CGFloat)arcLengthRadradius:(CGFloat)radiusarcMiddlePointAngle:(CGFloat)arcCenterRad {    /*    Calculate the hypotenuse of the larger, outer circle where the     points of the tangent lines would rest upon (imagine wrapping     the drawn circle in a bounding regular convex polygon of tangent     lines, then wrap that polygon in an outer circle)    */    float arcP1hyp = 1/cos(arcLengthRad/2) * radius;    // Build first tangent point    CGPoint arcP1 = (CGPoint){        arcCenter.x + cosf(arcCenterRad)*arcP1hyp,        arcCenter.y + sinf(arcCenterRad)*arcP1hyp    };    // Build the final endpoint of the arc    CGPoint arcP2final = (CGPoint){        arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius,        arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius    };    // Build second tangent point using the first tangent point and the final point of the arc.      // This point is resting on the bounding outer circle like arcP1 is.    // This would also work using the final point itself, using the simple assignment of arcP2 = arcP2final;      //   or of course simply omitting arcP2 altogether.    CGPoint arcP2 = (CGPoint){        (arcP2final.x - arcP1.x) + arcP2final.x,        (arcP2final.y - arcP1.y) + arcP2final.y    };    // The following adds an arc of a circle to the current path, using a radius and tangent points.    CGContextAddArcToPoint(context,                            arcP1.x,                            arcP1.y,                           arcP2.x,                            arcP2.y,                           radius);}