Skip to content

Instantly share code, notes, and snippets.

@j1r1k
Last active May 14, 2016 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j1r1k/4f70c0e431930ba3fa5b1b10810a54e1 to your computer and use it in GitHub Desktop.
Save j1r1k/4f70c0e431930ba3fa5b1b10810a54e1 to your computer and use it in GitHub Desktop.
PureScript by Example: Chapter 9 (Canvas Graphics) exercise 9.4.3
module RenderPath where
-- 3. (Medium) Given the following record type:
-- type Point = { x :: Number, y :: Number }
-- which represents a 2D point, write a function renderPath which strokes a closed path
-- constructed from a number of points:
--
-- renderPath :: forall eff. Context2D ->
-- Array Point ->
-- Eff (canvas :: Canvas | eff) Context2D
-- Given a function
-- f :: Number -> Point
-- which takes a Number between 0 and 1 as its argument and returns a Point , write an action
-- which plots f by using your renderPath function. Your action should approximate the path
-- by sampling f at a finite set of points.
import Prelude
import Data.Array
import Data.Maybe
import Control.Monad.Eff
import Graphics.Canvas
import Data.Foldable (traverse_)
import Data.Int (toNumber)
type Point = { x :: Number, y :: Number }
moveTo' ctx {x: x, y: y} = moveTo ctx x y
lineTo' ctx {x: x, y: y} = lineTo ctx x y
renderPath' :: forall eff. Context2D -> Point -> Array Point -> Eff (canvas :: Canvas | eff) Context2D
renderPath' ctx origin points = do
moveTo' ctx origin
traverse_ (lineTo' ctx) points
closePath ctx
renderPath :: forall eff. Context2D -> Array Point -> Eff (canvas :: Canvas | eff) Context2D
renderPath ctx input = fromMaybe (return ctx) $ do
origin <- head input
points <- tail input
return $ strokePath ctx $ renderPath' ctx origin points
sampleF :: Int -> (Number -> Point) -> Array Point
sampleF count f = map (\n -> f $ (toNumber n) / (toNumber count)) (0 .. count)
plotF :: forall eff. Context2D -> Int -> (Number -> Point) -> Eff (canvas :: Canvas | eff) Context2D
plotF ctx count f = renderPath ctx $ sampleF count f
main = do
Just canvas <- getCanvasElementById "canvas"
ctx <- getContext2D canvas
setStrokeStyle "#0000FF" ctx
renderPath ctx [ {x: 0.0, y: 0.0}
, {x: 50.0, y: 100.0}
, {x: 600.0, y: 100.0}
, {x: 50.0, y: 600.0}
]
setStrokeStyle "#00FF00" ctx
plotF ctx 100 $ \n -> { x: n * 600.0, y: n * n * 600.0 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment