Twinside / Rasterific

A drawing engine in Haskell
BSD 3-Clause "New" or "Revised" License
140 stars 11 forks source link

Disappearing cubic bezier dashes #45

Closed robx closed 6 years ago

robx commented 6 years ago

I've tried digging down into an issue with diagrams-rasterific where dashed circles loose dashes at low resolution: https://github.com/diagrams/diagrams-rasterific/issues/51

The test case included with the issue above results in a call to dashedStrokeWithOffset with

     [ CubicBezier (V2 34.0 20.0) (V2 34.0 12.268013) (V2 27.731987 6.0) (V2 20.0 6.0)
     , CubicBezier (V2 20.0 6.0) (V2 12.268013 6.0) (V2 6.0 12.268013) (V2 6.0 20.0)
     , CubicBezier (V2 6.0 20.0) (V2 6.0 27.731987) (V2 12.268013 34.0) (V2 20.0 34.0)
     , CubicBezier (V2 20.0 34.0) (V2 27.731987 34.0) (V2 34.0 27.731987) (V2 34.0 20.0)
     ]

I can sort of reproduce the problem in Rasterific proper with the following change to rastertest.hs (the dashing is not quite the same and it's messy):

diff --git a/exec-src/rastertest.hs b/exec-src/rastertest.hs
index 19d7d72..96bb93d 100644
--- a/exec-src/rastertest.hs
+++ b/exec-src/rastertest.hs
@@ -118,7 +118,8 @@ dashedStroke :: Geometry g
              => DashPattern -> Float -> Join -> (Cap, Cap) -> g
              -> Drawing PixelRGBA8 ()
 dashedStroke p w j c prims =
-    R.dashedStroke p w j c prims >> drawBoundingBox prims
+    drawBoundingBox prims >>
+    R.dashedStroke p w j c prims 

 dashedStrokeWithOffset
     :: Geometry g
@@ -286,6 +287,12 @@ strokeCubicDashed stroker texture prefix =
     cusp = CubicBezier (V2 10 230) (V2 350 570) (V2 10 570) (V2 350 230)
     loop = CubicBezier (V2 160 20) (V2 770 500) (V2 140 500) (V2 480 70)
     dashPattern = [10, 5, 20, 10]
+    circ =
+        [ CubicBezier (V2 34.0 20.0) (V2 34.0 12.268013) (V2 27.731987 6.0) (V2 20.0 6.0)
+        , CubicBezier (V2 20.0 6.0) (V2 12.268013 6.0) (V2 6.0 12.268013) (V2 6.0 20.0)
+        , CubicBezier (V2 6.0 20.0) (V2 6.0 27.731987) (V2 12.268013 34.0) (V2 20.0 34.0)
+        , CubicBezier (V2 20.0 34.0) (V2 27.731987 34.0) (V2 34.0 27.731987) (V2 34.0 20.0)
+        ]

     drawing = withTexture texture . sequence_ . concat $
         [ []
@@ -299,6 +306,7 @@ strokeCubicDashed stroker texture prefix =
         , [stroker dashPattern 25 (JoinMiter 0)
                 (CapStraight 0, CapStraight 0)
                 loop]
+        , [stroker [2, 2] 2 (JoinMiter 0) (CapStraight 0, CapStraight 0) circ]
         ]

At this point I'm a bit lost. Is this the right way to encode a circle in Rasterific? Should Rasterific handle the bezier dashing differently to avoid those gaps? Or should the diagrams backend stroke something else?

Twinside commented 6 years ago

I'll have a look soon, I hope it's not problems around some tolerance in the renderer :/