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.);;
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)