Last active
May 14, 2016 21:43
-
-
Save j1r1k/4f70c0e431930ba3fa5b1b10810a54e1 to your computer and use it in GitHub Desktop.
PureScript by Example: Chapter 9 (Canvas Graphics) exercise 9.4.3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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