-- | Lattice path diagrams -- -- For example, the code: -- -- > let u = UpStep -- > d = DownStep -- > path = [ u,u,d,u,u,u,d,u,d,d,u,d,u,u,u,d,d,d,d,d,u,d,u,u,d,d ] -- > drawLatticePath $ path -- -- produces the diagram: -- -- <> -- {-# LANGUAGE FlexibleContexts #-} module Math.Combinat.Diagrams.LatticePaths where -------------------------------------------------------------------------------- import Math.Combinat.LatticePaths import Linear.Vector import Data.Colour import Diagrams.Core import Diagrams.Prelude -------------------------------------------------------------------------------- -- | Which orientation to draw the lattice paths data LatticeConvention = Hilly -- ^ the steps are @(1,1)@ and @(1,-1)@ | UpRight -- ^ the steps are @(0,1)@ and @(0,1)@ deriving (Eq,Show) -------------------------------------------------------------------------------- -- | Draws a lattice path with the default settings drawLatticePath :: Renderable (Path V2 Double) b => LatticePath -> QDiagram b V2 Double Any drawLatticePath = drawLatticePath' Hilly red True drawLatticePath' :: Renderable (Path V2 Double) b => LatticeConvention -- ^ orientation -> Colour Double -- ^ color -> Bool -- ^ whether to draw a grid -> LatticePath -- ^ whether to draw a grid -> QDiagram b V2 Double Any drawLatticePath' convention color hasgrid xs = if hasgrid then path <> grid else path where {- path = go 0 0 ps where go !x !y [] = mempty go !x !y (p:ps) = case p of UpStep -> translate (r2 x y) up <> go (x+1) (y+1) ps DownStep -> translate (r2 x y) dn <> go (x+1) (y-1) ps -} linewidth = 0.025 path = path0 # lwL (linewidth*2) # lc color grid = grid0 # lwL (linewidth ) path0 = fromOffsets [ case p of { UpStep -> up ; DownStep -> dn } | p <- xs ] grid0 = case convention of Hilly -> drawRectangularGrid (length xs, pathHeight xs) UpRight -> drawRectangularGrid (b,a) (a,b) = pathNumberOfUpDownSteps xs (up,dn) = case convention of Hilly -> ( r2 (1,1) , r2 (1,-1) ) UpRight -> ( r2 (0,1) , r2 (1, 0) ) -------------------------------------------------------------------------------- -- | Draws a rectangular grid of the given size drawRectangularGrid :: Renderable (Path V2 Double) b => (Int,Int) -> QDiagram b V2 Double Any drawRectangularGrid (x,y) = grid # lc grey where grid = horiz <> vert horiz = mconcat [ translateY (fromIntegral i) hline | i<-[0..y] ] vert = mconcat [ translateX (fromIntegral j) vline | j<-[0..x] ] hline = fromOffsets [ (fromIntegral x) *^ unitX ] vline = fromOffsets [ (fromIntegral y) *^ unitY ] --------------------------------------------------------------------------------