Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not all subShapes returned from uniqueShapesCreatedFromSlicing for some Bezier paths #12

Open
prasad1120 opened this issue Jun 14, 2020 · 5 comments

Comments

@prasad1120
Copy link

Hi, I am trying to split the green part into 2 by considering the black box as the splitter path using uniqueShapesCreatedFromSlicing. It is working in most cases but there are some corner cases where it doesn't. Here, uniqueShapesCreatedFromSlicing returns 1 value in the array instead of 2.

Simulator Screen Shot - iPhone X - 2020-06-08 at 19 48 25

Note: Consider the black box to be complete.

let splitterPath = UIBezierPath(rect: someRect)
UIColor.black.setStroke()
splitterPath.lineWidth = 3
splitter.stroke()

UIColor.green.setFill()
splittingPath.fill()

// returns array with 1 element
let subShapes = splittingPath.uniqueShapesCreatedFromSlicing(withUnclosedPath: splitterPath) 

subShapes[0]!.fullPath().debugDescription:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(208.000000, 24.970562)];
[path addLineToPoint:CGPointMake(208.000000, 31.999998)];
[path addLineToPoint:CGPointMake(220.000000, 32.000000)];
[path addLineToPoint:CGPointMake(220.000000, 32.000000)];
[path addCurveToPoint:CGPointMake(211.514719, 28.485281) controlPoint1:CGPointMake(216.817402, 32.000000) controlPoint2:CGPointMake(213.765155, 30.735718)];
[path addLineToPoint:CGPointMake(208.000000, 24.970562)];
[path closePath];

splitterPath.debugDescription:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(12.000000, 16.970563)];
[path addLineToPoint:CGPointMake(208.000000, 16.970563)];
[path addLineToPoint:CGPointMake(208.000000, 128.000000)];
[path addLineToPoint:CGPointMake(12.000000, 128.000000)];
[path closePath];

splittingPath.debugDescription:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(12.000000, 32.000000)];
[path addCurveToPoint:CGPointMake(12.000000, 32.000000) controlPoint1:CGPointMake(12.000000, 32.000000) controlPoint2:CGPointMake(12.000000, 32.000000)];
[path addLineToPoint:CGPointMake(12.000000, 12.000000)];
[path addLineToPoint:CGPointMake(12.000000, 128.000000)];
[path addCurveToPoint:CGPointMake(12.000000, 128.000000) controlPoint1:CGPointMake(12.000000, 128.000000) controlPoint2:CGPointMake(12.000000, 128.000000)];
[path addLineToPoint:CGPointMake(208.000000, 128.000000)];
[path addLineToPoint:CGPointMake(208.000000, 128.000000)];
[path addCurveToPoint:CGPointMake(208.000000, 128.000000) controlPoint1:CGPointMake(208.000000, 128.000000) controlPoint2:CGPointMake(208.000000, 128.000000)];
[path addLineToPoint:CGPointMake(208.000000, 32.000000)];
[path addLineToPoint:CGPointMake(208.000000, 32.000000)];
[path addCurveToPoint:CGPointMake(208.000000, 32.000000) controlPoint1:CGPointMake(208.000000, 32.000000) controlPoint2:CGPointMake(208.000000, 32.000000)];
[path addLineToPoint:CGPointMake(220.000000, 32.000000)];
[path addLineToPoint:CGPointMake(220.000000, 32.000000)];
[path addCurveToPoint:CGPointMake(211.514719, 28.485281) controlPoint1:CGPointMake(216.817402, 32.000000) controlPoint2:CGPointMake(213.765155, 30.735718)];
[path addLineToPoint:CGPointMake(200.000000, 16.970563)];
[path addLineToPoint:CGPointMake(190.828427, 26.142136)];
[path addLineToPoint:CGPointMake(190.828427, 26.142136)];
[path addCurveToPoint:CGPointMake(176.686292, 32.000000) controlPoint1:CGPointMake(187.077700, 29.892863) controlPoint2:CGPointMake(181.990621, 32.000000)];
[path addLineToPoint:CGPointMake(12.000000, 32.000000)];
[path closePath];
@prasad1120 prasad1120 changed the title Not all subShapes returned from uniqueShapesCreatedFromSlicing for some bezierpaths Not all subShapes returned from uniqueShapesCreatedFromSlicing for some Bezier paths Jun 14, 2020
@adamwulf
Copy link
Owner

This is a strange one. It may take me a while to find the root cause, but in playing around with it I found that reversing the splitterPath with bezierPathByReversingPath gives the correct results of 2 shapes.

@prasad1120
Copy link
Author

I think I have found what was wrong. In the splittingPath, there is a place where the end of addLine doesn't end at the point from where addArc is supposed to start. I'm not aware how this fix that I made affected the splitting process. I'm able to get desired results now even without using bezierPathByReversingPath.

@adamwulf
Copy link
Owner

Glad you found a way to get it to work. Can you post the splitter and splitting paths that don't work unless you make that 1 adjustment to the addLine call? and post the fixed splitting path too? that'll help me track down the problem when i have the test case for fail/succeed with that one small change. thanks!

@prasad1120
Copy link
Author

prasad1120 commented Jun 15, 2020

No change was made in splitterPath

splitterPath.debugDescription:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(35.000000, 49.497475)];
[path addLineToPoint:CGPointMake(185.000000, 49.497475)];
[path addLineToPoint:CGPointMake(185.000000, 105.000000)];
[path addLineToPoint:CGPointMake(35.000000, 105.000000)];
[path closePath];

(before correction) splittingPath that returns 1 value after splitting:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(35.000000, 55.000000)];
[path addCurveToPoint:CGPointMake(35.000000, 55.000000) controlPoint1:CGPointMake(35.000000, 55.000000) controlPoint2:CGPointMake(35.000000, 55.000000)];
[path addLineToPoint:CGPointMake(35.000000, 35.000000)];
[path addLineToPoint:CGPointMake(35.000000, 105.000000)];
[path addCurveToPoint:CGPointMake(35.000000, 105.000000) controlPoint1:CGPointMake(35.000000, 105.000000) controlPoint2:CGPointMake(35.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 105.000000)];
[path addCurveToPoint:CGPointMake(185.000000, 105.000000) controlPoint1:CGPointMake(185.000000, 105.000000) controlPoint2:CGPointMake(185.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 55.000000)];
[path addLineToPoint:CGPointMake(185.000000, 55.000000)];
[path addCurveToPoint:CGPointMake(185.000000, 55.000000) controlPoint1:CGPointMake(185.000000, 55.000000) controlPoint2:CGPointMake(185.000000, 55.000000)];
[path addLineToPoint:CGPointMake(220.000000, 55.000000)];
[path addLineToPoint:CGPointMake(200.000000, 47.577787)];
[path addCurveToPoint:CGPointMake(173.786797, 55.000000) controlPoint1:CGPointMake(192.117733, 52.430540) controlPoint2:CGPointMake(183.043110, 55.000000)];
[path addLineToPoint:CGPointMake(35.000000, 55.000000)];
[path closePath];

(after correction) splittingPath that returns 2 values after splitting:

path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(35.000000, 55.000000)];
[path addCurveToPoint:CGPointMake(35.000000, 55.000000) controlPoint1:CGPointMake(35.000000, 55.000000) controlPoint2:CGPointMake(35.000000, 55.000000)];
[path addLineToPoint:CGPointMake(35.000000, 105.000000)];
[path addLineToPoint:CGPointMake(35.000000, 105.000000)];
[path addCurveToPoint:CGPointMake(35.000000, 105.000000) controlPoint1:CGPointMake(35.000000, 105.000000) controlPoint2:CGPointMake(35.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 105.000000)];
[path addCurveToPoint:CGPointMake(185.000000, 105.000000) controlPoint1:CGPointMake(185.000000, 105.000000) controlPoint2:CGPointMake(185.000000, 105.000000)];
[path addLineToPoint:CGPointMake(185.000000, 55.000000)];
[path addLineToPoint:CGPointMake(185.000000, 55.000000)];
[path addCurveToPoint:CGPointMake(185.000000, 55.000000) controlPoint1:CGPointMake(185.000000, 55.000000) controlPoint2:CGPointMake(185.000000, 55.000000)];
[path addLineToPoint:CGPointMake(220.000000, 55.000000)];
[path addLineToPoint:CGPointMake(200.000000, 47.577787)];
[path addCurveToPoint:CGPointMake(173.786797, 55.000000) controlPoint1:CGPointMake(192.117733, 52.430540) controlPoint2:CGPointMake(183.043110, 55.000000)];
[path addLineToPoint:CGPointMake(35.000000, 55.000000)];
[path closePath];

I hope this helps :)

@adamwulf
Copy link
Owner

awesome :) many thanks for this test case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants