Search code examples
ocamlbezier

Is this a reasonable implementation of the quadratic Bézier function in OCaml?


A friend came across a quadratic Bézier curve function in his codebase that used a gigantic rats nest of a switch table to perform the computation. He challenged me to find a single, short expression that would allow him to replace the gigantic block of code.

In attempting to satisfy two different curiosities, I thought I'd try implementing the function in OCaml. I'm a very novice OCaml programmer and I'm also unfamiliar with the function and this specific implementation is hard to come by via Google.

Critiques on both the function's performance/correctness as well as its implementation are very much appreciated.

Implementation of Quadratic Bézier Curve:

let rec b2 n =
  let p1 = -10. in
  let p2 = 10. in
  let q = n*.n in
  let rec b2i n i hd =
    if i > n then
      List.rev hd
    else
      let t = i /. n in
      b2i n (i+.1.) ((((1.-.t)**2.)*.p1+.(2.*.t*.(1.-.t)*.q)+.(t**2.)*.p2) :: hd)
  in 
  b2i n 0. []
;;

let floatprint lst = 
  List.iter (fun f -> Printf.printf "%f; " f) lst ;;

floatprint (b2 8.);;

Solution

  • b2 isn't recursive, so no need for [let rec b2 n =]. Since n never changes, no need to have it as argument to b2i, just use n from the enclosing scope. Your inner function should depend on p0, p1 and p2, but I see it depending on -10., n**2 and 10. The function also has the form of a map from [ 0.0; 1.0; 2.0; ...; n.0] to the final values. Could you write it:

    let b i = 
      let t = i /. n in
      let tminus = (1.-.t) in
      (tminus *. tminus *. p0) +. (2. *. t *. tminus *. p1) +. (t *. t * p2)
    in
    List.map b ([generate list 1.0; 2.0; ... n.0])
    

    A function to generate the list 1.0...n.0 could be: (for small n)

    let rec count m n = if m > n then [] else m :: (count (m+.1.) n)