Мортенфаст доказал, что это ошибка. Но я опубликую этот ответ, чтобы предложить мой обходной путь.
Обходной путь - обнаружить этот случай и добавить очень короткий отрезок линии, перпендикулярный существующей линии, примерно так:
- (void)addPtToPath:(CGPoint)newPt {
// CoreGraphics seems to have a bug if a path doubles back on itself.
// Detect that and apply a workaround.
CGPoint curPt = CGPathGetCurrentPoint(self.currentPath);
if (!CGPointEqualToPoint(newPt, curPt)) {
CGFloat slope1 = (curPt.y - prevPt.y) / (curPt.x - prevPt.x);
CGFloat slope2 = (curPt.y - newPt.y) / (curPt.x - newPt.x);
CGFloat diff;
BOOL between;
if (isinf(slope1) && isinf(slope2)) {
// Special-case vertical lines
diff = 0;
between = ((prevPt.y < curPt.y) != (curPt.y < newPt.y));
} else {
diff = slope1 - slope2;
between = ((prevPt.x < curPt.x) != (curPt.x < newPt.x));
}
if (between && diff > -0.1 && diff < 0.1) {
//NSLog(@"Hack alert! (%g,%g) (%g,%g) (%g,%g) => %g %g => %g", prevPt.x, prevPt.y, curPt.x, curPt.y, newPt.x, newPt.y, slope1, slope2, diff);
if (isinf(slope1)) {
curPt.x += 0.1;
} else if (slope1 == 0) {
curPt.y += 0.1;
} else if (slope1 < -1 || slope1 > 1) {
curPt.x += 0.1; curPt.y -= 0.1 / slope1;
} else {
curPt.x -= 0.1 * slope1; curPt.y += 0.1;
}
CGPathAddLineToPoint(self.currentPath, NULL, curPt.x, curPt.y);
}
prevPt = curPt;
}
CGPathAddLineToPoint(self.currentPath, NULL, newPt.x, newPt.y);
}
Для этого нужен один ивар с именем prevPt
, и он работает по пути в иваре currentPath
.