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

union does not produce expected result when used with difference #78

Open
bacchanalia opened this issue Feb 25, 2019 · 4 comments
Open

Comments

@bacchanalia
Copy link

In the following code ex3 should be the union of the the star with the ring, but instead union just returns the equivilent of ex2.

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
import Diagrams.Prelude
import Diagrams.Backend.Cairo.CmdLine
import Diagrams.TwoD.Polygons
import qualified Diagrams.TwoD.Path.Boolean as B

rose r1 r2 = polygon $ with
  & polyType   .~ PolyPolar (replicate 7 $ 1/8 @@ turn) (cycle [r1, r2])
  & polyOrient .~ NoOrient

ex1, ex2, ex3 :: Diagram Cairo
ex1 = stroke $ B.union Winding $ rose 1 3 <> circle 2                                     -- works
ex2 = stroke $ rose 1 3 <> B.difference Winding (circle 2) (circle 1.9)                   -- works
ex3 = stroke $ B.union Winding $ rose 1 3 <> B.difference Winding (circle 2) (circle 1.9) -- broken

main = mainWith (ex1 ||| ex2 ||| ex3)
@fryguybob
Copy link
Member

fryguybob commented Feb 26, 2019

I think something must be a little off in the direction of the paths that come from B.difference. If I reverse the result of the B.difference it works:

ex3 = stroke $ B.union Winding $ rose 1 3 <> (reversePath $ B.difference Winding (circle 2) (circle 1.9))

@byorgey
Copy link
Member

byorgey commented Feb 27, 2019

Ah, right @fryguybob , that jogged my memory. There was this similar bug that is now fixed: #67 but in general it seems this is a known issue with cubicbezier: kuribas/cubicbezier#6 .

@bacchanalia
Copy link
Author

Since there hasn't been any movement on this on the cubicbezier side, I'd like to fix this on the diagrams side, but I'd like some feedback on what the desired behaviour is. I can think of two reasonable interpretations:

  1. (simpler) Force all exterior loops to be counterclockwise, reversing interior paths as needed.
  2. (more expensive) For each exterior loop, if any point on it corresponds to a point on a counterclockwise input loop, force it to be counterclockwise, otherwise force it to be clockwise, reversing interior paths as needed.

@bacchanalia
Copy link
Author

I think option (2) actually requires the improvements to segmentSegment discussed in diagrams-lib issue #323 in order to be able to map sections of output looks back to input loops.

bacchanalia pushed a commit to bacchanalia/diagrams-contrib that referenced this issue Apr 10, 2019
Issue diagrams#78 "union does not produce expected result when used with
difference" occurs because difference is returning loops that wind the
opposite direction from what is expected. The solution is to enforce
that the outermost loops wind counterclockwise to be consistent with the
direction that the shape functions provided by diagrams-lib wind. A more
precise solution would be to match the winding of the outermost loops to
that of the input loops they are constructed from, but the intersection
functions in diagrams-lib do not currently support finding the
intersections between segments that overlap, which prevents us from
determining which input loops correspond to the outermost output loops.
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

3 participants