-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGraphic.elm
65 lines (53 loc) · 1.91 KB
/
Graphic.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module Graphic where
import Expression exposing (..)
import Graphics.Element as GE
import Graphics.Collage as C
import Color
import Eval as E
import ExpParser as Parser
type alias Range = (Float, Float)
-- now only plot single variable function
-- assuming all functions are univariate here
genPoints : Float -> Float -> Float -> List Float
genPoints step start end =
let diff = end - start in
let num = diff/step in
List.map (\n -> n*step + start) [0..num-1]
takeWhile : (a -> Bool) -> List a -> List a
takeWhile p xs =
case xs of
[] -> []
x::xs' -> if p x then x :: takeWhile p xs'
else []
dropWhile : (a -> Bool) -> List a -> List a
dropWhile p xs =
case xs of
[] -> []
x :: xs' -> if p x then dropWhile p xs'
else xs
separate : Float -> List Float -> List (List Float)
separate cutoff xs =
case xs of
[] -> [[]]
_ ->
let pred x = abs x <= cutoff in
takeWhile pred xs :: separate cutoff (dropWhile (not << pred) <| dropWhile pred xs)
separate1 : Float -> List (Float, Float) -> List (List (Float, Float))
separate1 cutoff xs =
case xs of
[] -> [[]]
_ -> let pred (x,y) = abs y <=cutoff in
takeWhile pred xs :: separate1 cutoff (dropWhile (not << pred) <| dropWhile pred xs)
plot : Range -> Float -> Exp -> GE.Element
plot range cutoff e =
let (start,end) = range in
let step = 0.01 in
let points = genPoints step start end in
let graph = List.map (\x -> (50*x, 50*E.evaluate x e)) points in
let graphs = separate1 cutoff graph in
let paths = List.map (C.traced C.defaultLine << C.path) graphs in
let xaxis = C.traced C.defaultLine <| C.segment (-150,0) (150,0) in
let yaxis = C.traced C.defaultLine <| C.segment (0,-150) (0,150) in
C.collage 400 400 <| xaxis :: yaxis :: paths
main : Signal GE.Element
main = Signal.constant <| plot (-2,2) 400 <| Parser.fromOk_ <| Parser.parse "1/x"