Рисование фактического треугольника / стрелки легко, если у вас есть две точки на вашем пути.
CGContextMoveToPoint( context , ax , ay );
CGContextAddLineToPoint( context , bx , by );
CGContextAddLineToPoint( context , cx , cy );
CGContextClosePath( context ); // for triangle
Получить очки немного сложнее. Вы сказали, что путь - это линия, а не кривая или серия кривых. Это облегчает.
Используйте CGPathApply, чтобы выбрать две точки на пути. Вероятно, это последние две точки, одна из которых может быть kCGPathElementMoveToPoint, а другая - kCGPathElementAddLineToPoint. Пусть mx, my будет первой точкой, а nx, ny - второй, поэтому стрелка будет указывать от m к n.
Если вы хотите, чтобы стрелка на конце линии, bx, сверху была равна nx, ny на линии. Выберите точку dx, dy между mx, my и nx, ny, чтобы вычислить другие точки.
Теперь вычислите ax, ay и cx, cy так, чтобы они были на линии с dx, dy и равноудалены от пути. Следующее должно быть близко, хотя я, вероятно, неправильно понял некоторые признаки:
r = atan2( ny - my , nx - mx );
bx = nx;
by = ny;
dx = bx + sin( r ) * length;
dy = by + cos( r ) * length;
r += M_PI_2; // perpendicular to path
ax = dx + sin( r ) * width;
ay = dy + cos( r ) * width;
cx = dx - sin( r ) * width;
cy = dy - cos( r ) * width;
Длина - это расстояние от вершины стрелки до основания, а ширина - это расстояние от оси до зубцов, или половина ширины головки стрелки.
Если путь - это кривая, то вместо нахождения mx, my в качестве предыдущей точки или движения, она будет конечной контрольной точкой последней кривой. Каждая контрольная точка находится на линии, касательной к кривой и проходящей через соседнюю точку.