Introduction to Cocoa Graphics, Part 2
Subject:   I figured it out!
Date:   2001-11-20 21:22:43
From:   retro
Response to: thinking in box, curve out of box ;-)

I believe I have the solution. The two points passed to this method serve as a guide for an imaginary line. That is, if you drew an infinitely long line which included the two points, that line is your guide. The method attempts to draw an arc with the specified radius from the current bezier path end point to another point somewhere on this line. The arc, as you noted, will always meet at a tangent to the imaginary line, and the direction the arc travels depends on the order of the two points specified. The imaginary line is actually a vector telling the arc as to which direction to travel.

I lack psheldon's linguistic capability to describe this as accurately as I would like, so here is some code to compile. I draw a line between the two guid points to show a segment of the imaginary line. You can see the direction of the arc come into play if you change the order in which you pass the two control points.

- (void)drawRect:(NSRect)rect {

NSPoint p1 = NSMakePoint(0, 100);
NSPoint p2 = NSMakePoint(80, 100);
NSPoint center = NSMakePoint(40, 160);
NSRect p2Rect = NSMakeRect(79, 99, 2, 2);
NSRect centerRect = NSMakeRect(39, 159, 2, 2);
NSBezierPath * p2Path;
NSBezierPath * centerPath;
NSBezierPath * wall;
NSBezierPath * barrier;

[[NSColor blackColor] set];
p2Path = [NSBezierPath bezierPathWithRect:p2Rect];
[p2Path stroke];

centerPath = [NSBezierPath bezierPathWithOvalInRect:centerRect];
[centerPath stroke];

// Constructing the path
wall = [NSBezierPath bezierPath];
[wall moveToPoint:p1];
[wall appendBezierPathWithArcFromPoint:center toPoint:p2 radius:60];
[wall stroke];

barrier = [NSBezierPath bezierPath];
[barrier moveToPoint:center];
[barrier lineToPoint:p2];
[barrier stroke];