Это зависит от ваших намерений. Если вам нужна ваша кривая, чтобы пройти через каждую вершину, вам лучше использовать другой сплайн, такой как сплайны Катмулла-Рома. Они имеют полезное свойство проходить через все контрольные точки кривой. Кривые Безье не имеют этого свойства; вместо этого кривая ограничена выпуклой оболочкой контрольных точек. Вы также должны знать, что вам придется использовать сплайн произвольно высокого порядка, чтобы избежать самопересечения, когда ваши контрольные точки расположены очень близко друг к другу.
Если у вас есть хорошо управляемые контрольные точки уже по часовой стрелке или против часовой стрелки, следующий код оценит и нарисует замкнутый сплайн Catmull-Rom, соединяющий точки.
#define SMOOTHNESS 20
for(NSUInteger i = 0; i <= pointCount; ++i) {
CGPoint p0 = points[(i + 0) % pointCount];
CGPoint p1 = points[(i + 1) % pointCount];
CGPoint p2 = points[(i + 2) % pointCount];
CGPoint p3 = points[(i + 3) % pointCount];
for(CGFloat t = 0; t <= 1; t += 1.0 / SMOOTHNESS) {
CGFloat t2 = t*t, t3 = t * t * t;
CGFloat x = 0.5 *((2 * p1.x) + (-p0.x + p2.x) * t + (2*p0.x - 5*p1.x + 4*p2.x - p3.x) * t2 + (-p0.x + 3*p1.x- 3*p2.x + p3.x) * t3);
CGFloat y = 0.5 *((2 * p1.y) + (-p0.y + p2.y) * t + (2*p0.y - 5*p1.y + 4*p2.y - p3.y) * t2 + (-p0.y + 3*p1.y- 3*p2.y + p3.y) * t3);
if(i == 0 && t == 0)
CGContextMoveToPoint(context, x, y);
else
CGContextAddLineToPoint(context, x, y);
}
}
CGContextStrokePath(context);
В результате:
![Polygon with smoothed vertices](https://i.imgur.com/CV7kS.png)