### Fri, 07 Jul 2006

#### Functional Triangles.

Our friend Mark Greenaway has been playing around with Ocaml. He's written a program that draws n-sided polygons (for odd n) and then draws lines between the midpoint of each line segment and the opposite vertex to show that all of those lines will coincide at a point which is the middle of the polygon.

Mark's solution to this problem is pretty typical of a programmer who comes to Ocaml from imperative languages. Typically it uses a bunch of for loops when better, more functional techniques exist .

Here's my solution to the problem:

```(* To compile this: ocamlc graphics.cma triangles2.ml -o triangles2 *)
open Graphics

let pi = 3.1415926535897932384626433832795
let window_width = 640
let window_height = 480

let gen_points count =
let cx = window_width / 2 in
let cy = window_height / 2 in
let ary = Array.create count 0 in
let radius = 0.9 *. float_of_int cy in
let delta_angle = 2.0 *. pi /. (float_of_int count) in
Array.mapi (fun i x ->
( cx + truncate (radius *. sin (float_of_int i *. delta_angle)),
cy + truncate (radius *. cos (float_of_int i *. delta_angle))
)) ary

let gen_outer_lines points =
set_color black ;
let (x, y) =  points.(Array.length points - 1) in
moveto x y ;
Array.iter (fun (x, y) -> lineto x y) points

let gen_center_lines points =
set_color red ;
let do_line sx sy ex ey =
moveto sx sy ;
lineto ex ey
in
let len = Array.length points in
let mid = len / 2 in
Array.iteri (fun i (sx, sy) ->
let (first, second) = ((i + mid) mod len, (i + mid + 1) mod len) in
let (ex1,  ey1) = points.(first) in
let (ex2,  ey2) = points.(second) in
do_line sx sy ((ex1 + ex2) / 2) ((ey1 + ey2) / 2)
) points

let _ =
let points = gen_points 5 in
open_graph " 640x480" ;
gen_outer_lines points ;
gen_center_lines points ;
set_color blue ;
Array.iter (fun (x, y) -> fill_circle x y 10) points ;