Advertisement
Guest User

Untitled

a guest
Dec 19th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.21 KB | None | 0 0
  1. -- This module is a starting point for implementing the Graph Drawing
  2. -- Calculator as described in Part II of the Standard Lab. You can use this
  3. -- directly, or just study it as an example of how to use threepenny-gui.
  4.  
  5. import ThreepennyPages
  6. import Graphics.UI.Threepenny.Core as UI
  7. import qualified Graphics.UI.Threepenny as UI
  8. import Expr
  9. import Data.Maybe
  10.  
  11. canWidth,canHeight :: Num a => a
  12. canWidth = 300
  13. canHeight = 300
  14.  
  15. main :: IO ()
  16. main = startGUI defaultConfig setup
  17.  
  18. setup :: Window -> UI ()
  19. setup window =
  20. do -- Create them user interface elements
  21. canvas <- mkCanvas canWidth canHeight -- The drawing area
  22. fx <- mkHTML "<i>f</i>(<i>x</i>)=" -- The text "f(x)="
  23. input <- mkInput 20 "x" -- The formula input
  24. draw <- mkButton "Draw graph" -- The draw button
  25. diffe <- mkButton "Differentiate function" -- The differentiate button
  26. zoom <- mkSlider (1, 20) 1
  27. -- The markup "<i>...</i>" means that the text inside should be rendered
  28. -- in italics.
  29.  
  30. -- Add the user interface elements to the page, creating a specific layout
  31. formula <- row [pure fx,pure input]
  32. getBody window #+ [column [pure canvas,pure formula,pure draw,pure diffe,pure zoom]]
  33.  
  34. -- Styling
  35. getBody window # set style [("backgroundColor","lightblue"),
  36. ("textAlign","center")]
  37. pure input # set style [("fontSize","14pt")]
  38.  
  39. -- Interaction (install event handlers)
  40. on UI.click draw $ \ _ -> readAndDraw input zoom canvas
  41. on UI.click diffe $ \ _ -> differentiateAndDraw input zoom canvas
  42. on valueChange' input $ \ _ -> readAndDraw input zoom canvas
  43. on valueChange' zoom $ \ _ -> readAndDraw input zoom canvas
  44.  
  45. differentiateAndDraw :: Element -> Element -> Canvas -> UI ()
  46. differentiateAndDraw input zoom canvas =
  47. do
  48. formula <- get value input
  49. set' value (showExpr (differentiate (fromJust (readExpr formula)))) input
  50. readAndDraw input zoom canvas
  51.  
  52. readAndDraw :: Element -> Element -> Canvas -> UI ()
  53. readAndDraw input zoom canvas =
  54. do -- Get the current formula (a String) from the input element
  55. formula <- get value input
  56. zoomV <- get value zoom
  57. let zoomRead = read zoomV :: Double
  58. case readExpr formula of
  59. Nothing -> return ()
  60. (Just expr) -> drawGraph expr zoomRead canvas
  61.  
  62.  
  63. drawGraph :: Expr -> Double -> Canvas -> UI ()
  64. drawGraph expr zoom canvas =
  65. do
  66. clearCanvas canvas
  67. set UI.fillStyle (UI.solidColor (UI.RGB 0 0 0)) (pure canvas)
  68. UI.fillText (showExpr expr) (10,canHeight/2) canvas
  69. path "blue" (points expr (0.1 / zoom) (canWidth, canHeight)) canvas
  70.  
  71.  
  72. points :: Expr -> Double -> (Int,Int) -> [Point]
  73. points expr scale (width, height) = zip [0.. (fromIntegral width)] [realToPix y | y <- realY]
  74. where
  75. realY = [eval expr $ pixToReal $ fromIntegral x | x <- [0..width]]
  76. -- converts a pixel x-coordinate to a real x-coordinate
  77. pixToReal :: Double -> Double
  78. pixToReal x = (x - fromIntegral (div width 2)) * scale
  79. -- converts a real y-coordinate to a pixel y-coordinate
  80. realToPix :: Double -> Double
  81. realToPix y = fromIntegral ((div height 2) - round (y / scale))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement