Lijst met functiepunten#

Voor het tekenen van de grafiek van een functie is het nodig om deze functie in een groot aantal punten uit te rekenen. We definiëren daarvoor een functie funcTuples.

Het resultaat van de functie funcTuples f start stop step is een lijst van functiepunten van de vorm van een tuple (paar) (x, f x), voor alle opeenvolgende punten x op het interval start..stop, in stappen van grootte step.

Voorbeeld: funcTuples sqr 0 4 1 geeft: [(0,0), (1,1), (2,4), (3,9), (4,16)] - voor sqr x = x * x.

In een volgende stap zetten we deze lijst van tuples om in een string, wat nodig is voor de SVG tekenfuncties. Voor het bovengenoemde voorbeeld krijgen we dan: "0,0 1,1 2,4 3,9 4,16".

We ontwikkelen de volgende functies:

  • xList start stop step - lijst met de opeenvolgende x-punten vanaf start

  • funcTuples f start stop step - lijst met (x, f x) tuples

  • tupleToPoint (a, b) - van (a, b) naar "a,b"

  • tuplesToPoints tuples - van tuple-list naar string als lijst van SVG-punten

We gebruiken de volgende definities:

import List exposing (..)

sqr x = x * x
<function> : number -> number
werkzelfuit = 0
0 : number
werkzelfuitList = []
[] : List a
werkzelfuitFunc x = x
<function> : a -> a

xList: lijst met x-punten#

De functie xList start stop step (waarbij we aannemen dat stop >= start) geeft de lijst met x-punten

[start+0*step, start+1*step, start+2*step, ..., stop]

waarbij stop = start + nrsteps * step. Voor deze punten berekenen we later de bijbehorende functiewaarden.

Ontwikkel deze functie in een aantal stappen:

  1. bepaal eerst het aantal stappen, nrsteps;

  2. maak vervolgens de lijst [0, 1, ... nrsteps] met de factoren voor step;

  3. schaal en verschuif de factoren-lijst tot start+k*step.

1. Bepaal het aantal stappen.

Het aantal stappen op het interval start..stop met stapgrootte 1 is stop - start. Voorbeeld: 1..10 telt 9 stappen.

Voor een willekeurige stapgrootte step geldt: het aantal stappen is gelijk aan (stop - start) / step. Omdat step een floating point getal kan zijn, bijvoorbeeld 0.5, moeten we het resultaat nog afronden (round) tot een geheel getal.

Voorbeeld: (vul voor stop, start en step verschillende waarden in)

round ((10 - 1) / 0.5)
18 : Int
nrsteps : Float -> Float -> Float -> Int
nrsteps start stop step = werkzelfuit
<function> : Float -> Float -> Float -> Int

2. Maak de lijst [0, 1, .. nrsteps].

Met behulp van de functie List.range a b maak je de lijst [a, a+1, …, b]

baselist = werkzelfuitList
[] : List a

3. Schaal en verschuif

Hiervoor pas je (via map) op elk punt van de lijst de functie toe: \x -> start + step * toFloat x. We moeten de parameter x, een Int, hier omzetten in een Float, omdat Elm geen gemengde Int - Float berekeningen kent.

Voorbeeld:

map werkzelfuitFunc baselist
[] : List b

Combineer de vorige elementen in de onderstaande functie:

xList start stop step =
  let
    steps = werkzelfuit
    steplist = werkzelfuitList
  in
    werkzelfuitList
<function> : a -> b -> c -> List d

Voorbeeld:

xList 1 10 0.5
[] : List a

Maak de lijst Functuples#

Gegeven de lijst met x-waarden, maak een lijst met tuples (x, fx).

Dit kan door de functie x -> (x, f x) via map op elk punt in de x-lijst toe te passen:

funcTuples f start stop end = 
  map werkzelfuitFunc (xList start stop end)
<function> : a -> c -> d -> e -> List b

Voorbeeld:

funcTuples sqr -3 3 0.5
[] : List b

Van tuple naar SVG-point#

Een SVP “point” is een string met twee getallen x en y gescheiden door een komma.

Voor het tekenen van de grafiek met behulp van SVG moeten we deze lijst in String-notatie omzetten.

Elk tupel van de vorm (x, fx) moet dan omgezet worden in de string: “x,fx” - gescheiden door spaties.

tupleToPoint (a, b) =
  String.fromFloat a ++ "," ++ String.fromFloat b
<function> : ( Float, Float ) -> String

Voorbeeld:

tupleToPoint (2, 4)
"2,4" : String

van functiepunten-lijst naar SVG points-string#

Maak een functie tuplesToPoints tuples met als resultaat een string die bestaat uit SVG “points” (gemaakt uit de tuples) gescheiden door spaties.

Doe dit in twee stappen:

(1) pas de functie tupleToPoint (via map) toe op de lijst met tuples; het resultaat is een lijst van points

werkzelfuitList
[] : List a

(2) combineer de elementen uit deze lijst door middel van ++" "++ tussen de elementen. Gebruik daarvoor foldr met de onderstaande functie:

connect a b =
    a ++ " " ++ b
<function> : String -> String -> String
foldr connect "" werkzelfuitList
"" : String

(Wat gebeurt er als je foldr vervangt door foldl?)

Werk nu de functie tuplesToPoints uit.

tuplesToPoints tuples = ""
<function> : a -> String

De volgende functies gebruik je straks voor het tekenen van de polynoom:

  • xList start stop step

  • funcTuples f start stop step

  • tupleToPoint (a, b)

  • tuplesToPoints tlst