(* To compile this example: ocamlc graphics.cma triangles.ml -o triangles *) open Graphics;; let pi = 3.1415926535897932384626433832795 let window_width = 640 let window_height = 480 let sides = 5; type point = { x: int; y: int} let average a b = (a + b) / 2 let mid a b = { x = average a.x b.x; y = average a.y b.y } let distance a b = sqrt(float(b.x-a.x)**2.0 +. float(b.y-a.y)**2.0) let rotate pt origin angle = let r = distance pt origin in let rise = pt.y-origin.y in let run = pt.x-origin.x in let theta = atan (float(rise) /. float(run)) in { x = origin.x + truncate(r *. cos(theta +. angle)); y = origin.y + truncate(r *. sin(theta +. angle)) } let print_pt pt = Printf.printf "%d,%d\n" pt.x pt.y let round x = int_of_float (x +. 0.5) let even x = x mod 2 == 0 (* Translate to and from screen co-ordinates. I want the origin to be at the centre of the window. *) let from_screen pt = { x = pt.x - window_width/2; y = pt.y - window_height/2 } let to_screen pt = { x = -pt.x + window_width/2; y = -pt.y + window_height/2 } let () = let screen_topleft = { x=0; y=0; } in let screen_topright = { x=639; y=0 } in let screen_bottomleft = { x=0; y=479; } in let screen_bottomright = { x=639; y=479 } in let topleft = from_screen(screen_topleft) in let topright = from_screen(screen_topright) in let bottomleft = from_screen(screen_bottomleft) in let bottomright = from_screen(screen_bottomright) in let o = mid topleft bottomright in let deg_to_rad deg = (deg*. pi)/.180.0 in let a = mid topleft topright in let points = Array.create sides a in for i = 1 to sides - 1 do points.(i) <- rotate a o ((deg_to_rad 360.0 /. float(sides)) *. float(i)); done; let screen_o = (to_screen o) in let screen_points = Array.map to_screen points in open_graph " 640x480"; let pt_moveto pt = moveto pt.x pt.y in let pt_lineto pt = lineto pt.x pt.y in (* Draw points, then lines *) set_color blue; for i = 0 to Array.length screen_points - 1 do fill_circle screen_points.(i).x screen_points.(i).y 10 done; set_color black; let l = Array.length screen_points in for i = 0 to l - 1 do pt_moveto screen_points.(i); pt_lineto screen_points.((i + 1) mod l); done; let midpoints = Array.create l o in for i = 0 to l - 1 do midpoints.(i) <- (mid screen_points.(i) screen_points.((i + 1) mod l)); done; set_color red; let f = round (float(sides) /. 2.0) in for i = 0 to l - 1 do pt_moveto screen_points.((i + f) mod l); pt_lineto midpoints.(i); done; ignore(read_line())