generative-art-0.1.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Draw.Plotting

Description

Functions to generate GCode, suitable for being run on a penplotter.

(image code)

Expand
>>> :{
D.haddockRender "Draw/Plotting/example.svg" 300 200 $ \_ -> do
    let haskellLogo' = transform mirrorYCoords haskellLogo
        geometry = transform (transformBoundingBox haskellLogo' (shrinkBoundingBox 10 [zero, Vec2 300 200]) def) haskellLogo'
        plotSettings = def { _canvasBoundingBox = Just (boundingBox [zero, Vec2 300 200]) }
        plotResult = runPlot def $ do
            for_ geometry $ \logoPart -> plot logoPart
    _plotPreview plotResult
:}
Generated file: size 10KB, crc32: 0x1e175925
Synopsis

Plot type

data Plot a Source #

Plot represents penplotting directives, and is manipulated using functions such as plot and gCode.

Instances

Instances details
Applicative Plot Source # 
Instance details

Defined in Draw.Plotting

Methods

pure :: a -> Plot a #

(<*>) :: Plot (a -> b) -> Plot a -> Plot b #

liftA2 :: (a -> b -> c) -> Plot a -> Plot b -> Plot c #

(*>) :: Plot a -> Plot b -> Plot b #

(<*) :: Plot a -> Plot b -> Plot a #

Functor Plot Source # 
Instance details

Defined in Draw.Plotting

Methods

fmap :: (a -> b) -> Plot a -> Plot b #

(<$) :: a -> Plot b -> Plot a #

Monad Plot Source # 
Instance details

Defined in Draw.Plotting

Methods

(>>=) :: Plot a -> (a -> Plot b) -> Plot b #

(>>) :: Plot a -> Plot b -> Plot b #

return :: a -> Plot a #

MonadReader PlottingSettings Plot Source # 
Instance details

Defined in Draw.Plotting

MonadState PlottingState Plot Source # 
Instance details

Defined in Draw.Plotting

runPlot :: PlottingSettings -> Plot a -> RunPlotResult Source #

Run the Plot to easily generate the resulting GCode file. For convenience, this also generates a Cairo-based preview of the geometry.

let plotResult = runPlot settings body
writeGCodeFile "output.g" plotResult
renderPreview "output.png" 3 plotResult

data GCode Source #

Raw GCode for penplotting.

Instances

Instances details
Show GCode Source # 
Instance details

Defined in Draw.Plotting.GCode

Methods

showsPrec :: Int -> GCode -> ShowS #

show :: GCode -> String #

showList :: [GCode] -> ShowS #

Eq GCode Source # 
Instance details

Defined in Draw.Plotting.GCode

Methods

(==) :: GCode -> GCode -> Bool #

(/=) :: GCode -> GCode -> Bool #

Ord GCode Source # 
Instance details

Defined in Draw.Plotting.GCode

Methods

compare :: GCode -> GCode -> Ordering #

(<) :: GCode -> GCode -> Bool #

(<=) :: GCode -> GCode -> Bool #

(>) :: GCode -> GCode -> Bool #

(>=) :: GCode -> GCode -> Bool #

max :: GCode -> GCode -> GCode #

min :: GCode -> GCode -> GCode #

renderPreview Source #

Arguments

:: FilePath 
-> Double

Output resolution in px/mm

-> RunPlotResult 
-> IO () 

data RunPlotResult Source #

Result of runPlot; unifies convenience API and internals for tinkering.

Constructors

RunPlotResult 

Fields

data PlottingSettings Source #

Constructors

PlottingSettings 

Fields

  • _feedrate :: Double

    Initial feedrate. Can be modified locally with withFeedrate. (default: 1000)

  • _zTravelHeight :: Double

    During travel motion, keep the pen at this height (in absolute coordinates). (default: 1)

  • _zDrawingHeight :: Double

    When drawing, keep the pen at this height (in absolute coordinates). (default: -1)

  • _zLoweringFeedrate :: Maybe Double

    Use this feedrate for lowering the pen. On fast machines, lowering it at max speed might lead to unwanted vibrations. Nothing means as fast as possible. (default: Nothing)

  • _finishMove :: Maybe FinishMove

    Do a final move after the drawing has ended. (default: Nothing)

  • _previewDrawnShapesBoundingBox :: Bool

    At the beginning of the plot, trace the bounding box of all the GCode before actually drawing? Useful as a final check. (default: True)

  • _canvasBoundingBox :: Maybe BoundingBox

    The canvas we’re painting on. Useful to check whether the pen leaves the drawing area. (default: Nothing)

    (image code)

    Expand
    >>> paper = boundingBox [zero, Vec2 300 200]
    >>> haskellLogo' = transform mirrorYCoords haskellLogo
    >>> geometry = transform (rotateAround (boundingBoxCenter paper) (deg 40) <> transformBoundingBox haskellLogo' (shrinkBoundingBox 10 paper) def) haskellLogo'
    >>> plotSettings = def { _canvasBoundingBox = Just paper }
    >>> plotResult = runPlot plotSettings (for_ geometry plot)
    >>> renderPreview "docs/haddock/Draw/Plotting/leaving_the_canvas.svg" 1 plotResult
    
  • _previewPenWidth :: Double

    Use this line width in the preview. To get a realistic preview, match this value with the actual stroke width of your pen. (default: 1)

  • _previewPenColor :: Color Double

    Use this color for drawings in the preview. To get a realistic preview, match this value with the actual color of your pen. (default: mma 1)

  • _previewPenTravelColor :: Maybe (Color Double)

    Use this color for indicating pen travel in the preview. Nothing will disable pen travel preview. (default: Just (mma 0))

  • _previewDecorate :: Bool

    Show additional decoration in the preview, like origin and bounding box. (default: True)

Instances

Instances details
Show PlottingSettings Source # 
Instance details

Defined in Draw.Plotting

Default PlottingSettings Source # 
Instance details

Defined in Draw.Plotting

Eq PlottingSettings Source # 
Instance details

Defined in Draw.Plotting

MonadReader PlottingSettings Plot Source # 
Instance details

Defined in Draw.Plotting

data FinishMove Source #

Command to issue after all drawing is finished

Constructors

FinishWithG28

G28: go to predefined position

FinishWithG30

G30: go to predefined position

FinishTopRight

Move to the top right of the union of drawn and canvas BoundingBox.

Instances

Instances details
Show FinishMove Source # 
Instance details

Defined in Draw.Plotting

Eq FinishMove Source # 
Instance details

Defined in Draw.Plotting

Ord FinishMove Source # 
Instance details

Defined in Draw.Plotting

Raw GCode handling

data TinkeringInternals Source #

Constructors

TinkeringInternals 

Fields

renderGCode :: [GCode] -> Text Source #

Convert GCode to Text, to be written to a file.

Plotting shapes

class Plotting a where Source #

Draw a shape by lowering the pen, setting the right speed, etc. The specifics are defined in the configuration given in runPlot, or by the various utility functions such as withFeedrate or withDrawingHeight

Methods

plot :: a -> Plot () Source #

Instances

Instances details
Plotting Bezier Source #

FluidNC doesn’t support G05, so we approximate Bezier curves with line pieces. We use the naive Bezier interpolation bezierSubdivideEquiparametric, because it just so happens to put more points in places with more curvature.

Instance details

Defined in Draw.Plotting

Methods

plot :: Bezier -> Plot () Source #

Plotting BoundingBox Source #

Trace the bounding box without actually drawing anything to estimate result size

Instance details

Defined in Draw.Plotting

Methods

plot :: BoundingBox -> Plot () Source #

Plotting Circle Source # 
Instance details

Defined in Draw.Plotting

Methods

plot :: Circle -> Plot () Source #

Plotting Ellipse Source #

Approximation by a number of points

Instance details

Defined in Draw.Plotting

Methods

plot :: Ellipse -> Plot () Source #

Plotting Line Source # 
Instance details

Defined in Draw.Plotting

Methods

plot :: Line -> Plot () Source #

Plotting Polygon Source # 
Instance details

Defined in Draw.Plotting

Methods

plot :: Polygon -> Plot () Source #

Plotting Polyline Source # 
Instance details

Defined in Draw.Plotting

Methods

plot :: Polyline -> Plot () Source #

(Functor f, Sequential f, Plotting a) => Plotting (f a) Source #

Draw each element (in order)

Instance details

Defined in Draw.Plotting

Methods

plot :: f a -> Plot () Source #

(Plotting a, Plotting b) => Plotting (a, b) Source #

Draw each element (in order)

Instance details

Defined in Draw.Plotting

Methods

plot :: (a, b) -> Plot () Source #

(Plotting a, Plotting b, Plotting c) => Plotting (a, b, c) Source #

Draw each element (in order)

Instance details

Defined in Draw.Plotting

Methods

plot :: (a, b, c) -> Plot () Source #

(Plotting a, Plotting b, Plotting c, Plotting d) => Plotting (a, b, c, d) Source #

Draw each element (in order)

Instance details

Defined in Draw.Plotting

Methods

plot :: (a, b, c, d) -> Plot () Source #

(Plotting a, Plotting b, Plotting c, Plotting d, Plotting e) => Plotting (a, b, c, d, e) Source #

Draw each element (in order)

Instance details

Defined in Draw.Plotting

Methods

plot :: (a, b, c, d, e) -> Plot () Source #

Plotting primitives

repositionTo :: Vec2 -> Plot () Source #

Quick move for repositioning (without drawing).

lineTo :: Vec2 -> Plot () Source #

Draw a line from the current position to a target.

clockwiseArcAroundTo Source #

Arguments

:: Vec2

Center location

-> Vec2

End position

-> Plot () 

Arc interpolation, clockwise

counterclockwiseArcAroundTo Source #

Arguments

:: Vec2

Center location

-> Vec2

End position

-> Plot () 

Arc interpolation, counterclockwise

previewCanvas :: Plot () Source #

Trace the plotting area to preview the extents of the plot, and wait for confirmation. Useful at the start of a plot.

pause :: PauseMode -> Plot () Source #

Pause the plot for later resumption at the current state.

data PauseMode Source #

Constructors

PauseUserConfirm

Wait until user confirmation, e.g. in a web UI or with a button. (M0/Pause)

PauseSeconds Double

Wait for a certain time (G4/Dwell)

Instances

Instances details
Show PauseMode Source # 
Instance details

Defined in Draw.Plotting

Eq PauseMode Source # 
Instance details

Defined in Draw.Plotting

Ord PauseMode Source # 
Instance details

Defined in Draw.Plotting

withFeedrate :: Double -> Plot a -> Plot a Source #

Locally change the feedrate

withDrawingHeight :: Double -> Plot a -> Plot a Source #

Locally adapt the z drawing height (e.g. for changing pen pressure)

drawingDistance :: Plot Double Source #

Distance drawn so far.

One use case is adding a pause when a pencil needs sharpening again.

File structure

block :: Plot a -> Plot a Source #

Group the commands generated by the arguments in a block. This is purely cosmetical for the generated GCode.

comment :: Text -> Plot () Source #

Add a GCode comment.

Raw G-Code

penDown :: Plot () Source #

If the pen is up, lower it to drawing height. Do nothing if it is already lowered.

penUp :: Plot () Source #

If the pen is down, lift it to travel height. Do nothing if it is already lifted.

gCode :: [GCode] -> Plot () Source #

Add raw GCode to the output.

Utilities

minimizePenHovering Source #

Arguments

:: Sequential vector 
=> Set (vector Vec2)

Elements of this set will be sorted in optimized order. The elements themselves remain untouched.

-> [Vector Vec2] 

Sort a collection of polylines so that between each line pair, we only do the shortest move. This is a local solution to what would be TSP if solved globally. Better than nothing I guess, although this algorithm here is \(\mathcal O(n^2)\).

minimizePenHoveringBy :: Ord a => MinimizePenHoveringSettings a -> Set a -> [a] Source #

Similar to minimizePenHovering, but for arbitrary objects with a given start and end point.