diagrams / diagrams-contrib

User-contributed extensions to diagrams
BSD 3-Clause "New" or "Revised" License
27 stars 31 forks source link

Iterated path intersection producing an empty path #67

Closed byorgey closed 7 years ago

byorgey commented 7 years ago

Consider this code:

{-# LANGUAGE FlexibleContexts          #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeFamilies              #-}

import           Diagrams.Backend.Rasterific.CmdLine
import           Diagrams.Path                       (pathPoints)
import           Diagrams.Prelude
import qualified Diagrams.TwoD.Path.Boolean          as B

circles :: [Path V2 Double]
circles = iterateN 3 (rotateBy (1/3)) (circle 1 # translateX 0.5)

circlesDia :: Diagram B
circlesDia = circles # mconcat # stroke

lensPath :: Path V2 Double
lensPath = B.intersection Winding (circles !! 0) (circles !! 1)

-- This path is empty, but shouldn't be
errorPath :: Path V2 Double
errorPath = B.intersection Winding lensPath (circles !! 2)

circlesDia looks like this:

intersecttest

lensPath, where we intersect two of the circles, seems to work just fine:

ghci> lensPath
Path [Trail (loopFromSegments [bézier3  (V2 0.0 0.5522847537627503) (V2 0.4477152358979708 0.9999999896607211) (V2 0.9999999896607211 0.9999999896607211),bézier3  (V2 2.5473641729772234e-2 0.0) (V2 5.0724894523808295e-2 (-9.525295140588863e-4)) (V2 7.572001755463481e-2 (-2.8238477147032315e-3)),bézier3  (V2 1.4118009150652533e-2 (-2.0710720954396966e-2)) (V2 2.7568578289016044e-2 (-4.210254217512088e-2)) (V2 4.030539915390208e-2 (-6.41634426386184e-2)),bézier3  (V2 9.092210446573079e-2 (-0.15748182886766793)) (V2 0.13414150901098587 (-0.32941456727689056)) (V2 0.13414150901098587 (-0.49906617986433355)),bézier3  (V2 0.0 (-0.3456025147218976)) (V2 (-0.1793561302610085) (-0.6817390198057306)) (V2 (-0.500166923134703) (-0.8669592239201048)),bézier3  (V2 (-0.1812747129406237) (-0.10465899252872746)) (V2 (-0.38169673076101307) (-0.14611212622688918)) (V2 (-0.57574692308545) (-0.13119745106074954))] (openCubic (V2 (-0.10994154936770223) 0.1605951373654329) (V2 (-0.17425306916009092) 0.354892307082874))) `at` P (V2 (-0.49999999483036056) 0.0)]

lens

But intersecting the resulting lensPath with the third circle produces the empty path:

ghci> errorPath
Path []

But it shouldn't be empty; we should get the Reuleaux triangle in the middle.

byorgey commented 7 years ago

Not sure yet if this is a problem with the diagrams-contrib module itself, or if it's a bug in the underlying cubicbezier library.

byorgey commented 7 years ago

This seems to be fixed in cubicbezier-0.6: