diff --git a/BezierKit/BezierKitTests/Path+VectorBooleanTests.swift b/BezierKit/BezierKitTests/Path+VectorBooleanTests.swift index 15fe937..48e7e74 100644 --- a/BezierKit/BezierKitTests/Path+VectorBooleanTests.swift +++ b/BezierKit/BezierKitTests/Path+VectorBooleanTests.swift @@ -477,6 +477,16 @@ class PathVectorBooleanTests: XCTestCase { XCTAssertTrue(componentsEqualAsideFromElementOrdering(result.components[0], square.components[0])) } + func testCrossingsRemovedSingleCurveLoop() { + let cgPath = CGMutablePath() + cgPath.move(to: CGPoint(x: 0, y: 0)) + cgPath.addCurve(to: CGPoint(x: 0, y: 0), + control1: CGPoint(x: -1, y: 1), + control2: CGPoint(x: 1, y: 1)) + let path = Path(cgPath: cgPath) + XCTAssertEqual(path.crossingsRemoved(), path) + } + func testCrossingsRemovedEdgeCase() { // this is an edge cases which caused difficulty in practice // the contour, which intersects at (1,1) creates two squares, one with -1 winding count diff --git a/BezierKit/Library/PathComponent.swift b/BezierKit/Library/PathComponent.swift index 74fbe65..3ff5149 100644 --- a/BezierKit/Library/PathComponent.swift +++ b/BezierKit/Library/PathComponent.swift @@ -371,7 +371,10 @@ open class PathComponent: NSObject, Reversible, Transformable, @unchecked Sendab if i1 == i2 { // we are intersecting a path element against itself (only possible with cubic or higher order) if self.order(at: i1) == 3 { - elementIntersections = self.cubic(at: i1).selfIntersections + elementIntersections = self.cubic(at: i1).selfIntersections.filter { + guard self.numberOfElements == 1 else { return true } + return $0.t1 != 0 || $0.t2 != 1 // exclude intersection of single curve path closing itself + } } } else if i1 < i2 { // we are intersecting two distinct path elements