У меня необычная проблема, из-за которой мой разум застрял. Я создал приложение для рисования, использующее CGPathes, которое создается инструментом «на лету» с помощью следующего кода контроллера вида.
@implementation WWLGrabManager
- (void) touchesBegan:(NSSet*)touchesIgnore withEvent:(UIEvent*)event {
currentPath = CGPathCreateMutable();
CGPathMoveToPoint(currentPath, NULL, pt.x, pt.y);
}
- (void) touchesMoved:(NSSet*)touchesIgnore withEvent:(UIEvent*)event {
CGPathAddLineToPoint(currentPath, NULL, pt.x, pt.y);
}
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
currentPath = [self newSmoothedPathWithPath:currentPath];
}
@end
После рисования я повторяю еще раз по CGPath, чтобы сгладить нарисованные края пути. Это должно сделать путь не таким уродливым, построив середину каждой из трех точек и применив кривую к каждой точке. Код для сглаживания ребер в основном состоит из следующего псевдокода:
-(CGMutablePathRef)newSmoothedPathWithPath:(CGPathRef)path {
// This is pseudo code
CGMutablePathRef newPath = CGPathCreateMutable();
foreach (CGPoint point in path)
CGPathAddCurveToPoint(newPath, NULL,
ctrlPt1.x,ctrlPt1.y,ctrlPt2.x,ctrlPt2.y,
((*preLastPoint).x + (*lastPoint).x + (point).x)/3,
((*preLastPoint).y + (*lastPoint).y + (point).y)/3);
}
return newPath;
}
Теперь, после применения функции сглаживания, новый CGPath вызывает фрагменты, как на рисунке здесь . Я дважды проверил контрольные точки, но не могу понять, почему это происходит.
По причинам отладки я распечатал журнал точек CGPathes и контрольных точек ниже.
MainPoint // ControlPoint1 // ControlPoint2
66.00, 91.00 // 67.00,87.00 // 64.25,95.75
59.00,110.00 // 60.75,105.25 // 58.00,113.75
55.00,125.00 // 56.00,121.25 // 54.00,128.75
51.00,140.00 // 52.00,136.25 // 50.25,144.25
48.00,157.00 // 48.75,152.75 // 47.25,161.00
45.00,173.00 // 45.75,169.00 // 44.75,176.75
44.00,188.00 // 44.25,184.25 // 43.75,191.75
43.00,203.00 // 43.25,199.25 // 43.00,207.00
43.00,219.00 // 43.00,215.00 // 43.00,223.00
43.00,235.00 // 43.00,231.00 // 43.00,239.25
43.00,252.00 // 43.00,247.75 // 43.00,256.00
43.00,268.00 // 43.00,264.00 // 44.25,272.00
48.00,284.00 // 46.75,280.00 // 49.50,287.50
54.00,298.00 // 52.50,294.50 // 56.75,300.75
65.00,309.00 // 62.25,306.25 // 68.75,310.75
80.00,316.00 // 76.25,314.25 // 84.00,316.50
96.00,318.00 // 92.00,317.50 // 101.50,318.25
118.00,319.00 // 112.50,318.75 // 124.75,319.00
145.00,319.00 // 138.25,319.00 // 151.25,319.00
170.00,319.00 // 163.75,319.00 // 175.50,318.25
192.00,316.00 // 186.50,316.75 // 199.50,314.00
222.00,308.00 // 214.50,310.00 // 226.75,306.75
241.00,303.00 // 236.25,304.25 // 245.00,301.75
257.00,298.00 // 253.00,299.25 // 260.50,295.75
271.00,289.00 // 267.50,291.25 // 273.25,285.25
280.00,274.00 // 277.75,277.75 // 280.50,270.25
282.00,259.00 // 281.50,262.75 // 282.00,254.50
282.00,241.00 // 282.00,245.50 // 280.50,237.25
276.00,226.00 // 277.50,229.75 // 273.50,222.75
266.00,213.00 // 268.50,216.25 // 263.00,208.75
254.00,196.00 // 257.00,200.25 // 249.75,192.50
237.00,182.00 // 241.25,185.50 // 234.00,179.75
225.00,173.00 // 228.00,175.25 // 221.75,170.50
212.00,163.00 // 215.25,165.50 // 208.50,160.25
198.00,152.00 // 201.50,154.75 // 194.00,148.75
182.00,139.00 // 186.00,142.25 // 178.00,136.75
166.00,130.00 // 170.00,132.25 // 162.25,128.50
Обновление: Я использовал алгоритм, описанный в по этой ссылке , который был переведен в Objective-C следующим образом:
CGPoint ctrl2 = controlPointForPoints(*lastPoint,*preLastPoint,currentPoint);
CGPoint ctrl1 = controlPointForPoints(*lastPoint,currentPoint,*preLastPoint);
static CGPoint controlPointForPoints(CGPoint pt, CGPoint pre, CGPoint post) {
CGPoint ctrlPt = CGPointMake(
middleOfPoints(middleOfPoints(pt.x, pre.x), middleOfPoints(symmetryOfPoints(pt.x, post.x), pt.x)),
middleOfPoints(middleOfPoints(pt.y, pre.y), middleOfPoints(symmetryOfPoints(pt.y, post.y), pt.y))
);
return ctrlPt;
}
static float symmetryOfPoints(float a,float b) {
return a - ((b-a)*smoothingFactor) / 100.0;
}
static float middleOfPoints(float a, float b) {
return (a+b) / 2.0;
}
Однако обмен двумя контрольными точками не приводит к удовлетворительным результатам, а увеличивает количество фрагментов до огромных размеров. Буду признателен за любую дополнительную помощь.