106 lines
3.4 KiB
OCaml
106 lines
3.4 KiB
OCaml
open Graphics ;;
|
|
|
|
let pi = 3.14159265358979343 ;;
|
|
|
|
let rec ln10 n = match n with
|
|
| k when k < 0 -> failwith "Are you sure about that ?"
|
|
| k when k < 10 -> 0
|
|
| k -> 1 + ln10 (k/10) ;;
|
|
|
|
let delta i j =
|
|
if i = j then 1 else 0 ;;
|
|
|
|
let draw_integer x0 y n0 r =
|
|
(* 7-seg display *)
|
|
let n = ref n0 in
|
|
let size = ln10 n0 in
|
|
let len = r/3 in
|
|
let offset = size*(len/2) in
|
|
for i = 0 to size do
|
|
let x = x0 - (-(1 - delta size 0)*8 - offset + i * (len+8)) in
|
|
if Array.mem (!n mod 10) [|0; 4; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y+len); (x-len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y+len); (x+len/2, y+len)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 1; 2; 3; 4; 7; 8; 9|] then
|
|
draw_poly_line [|(x+len/2, y+len); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|2; 3; 4; 5; 6; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 1; 3; 4; 5; 6; 7; 8; 9|] then
|
|
draw_poly_line [|(x+len/2, y-len); (x+len/2, y)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 3; 5; 6; 8; 9|] then
|
|
draw_poly_line [|(x-len/2, y-len); (x+len/2, y-len)|];
|
|
|
|
if Array.mem (!n mod 10) [|0; 2; 6; 8|] then
|
|
draw_poly_line [|(x-len/2, y-len); (x-len/2, y)|];
|
|
|
|
n := !n/10;
|
|
done ;;
|
|
|
|
let identity n = n ;;
|
|
|
|
let improved_pretty_printing g wd ht r =
|
|
let n = Array.length g in
|
|
let coords = Array.make n (0, 0) in
|
|
|
|
let colors = Array.make n (rgb 0 0 0) in
|
|
for i = 0 to n-1 do
|
|
colors.(i) <- rgb ((255 * i) / n) ((255*(i+n/3)) / n) ((255*(2*i+n/3)) / n)
|
|
done;
|
|
|
|
for k = 0 to n-1 do
|
|
let theta = 2. *. pi *. (float_of_int k) /. (float_of_int (n)) +. pi /. (float_of_int (n)) in
|
|
let i = ref (int_of_float ((float_of_int wd) /. 2.) + int_of_float ((float_of_int wd) /. 2.2 *. cos theta)) in
|
|
let j = ref (int_of_float ((float_of_int ht) /. 2.) + int_of_float ((float_of_int ht) /. 2.2 *. sin theta)) in
|
|
set_line_width 8 ;
|
|
set_color colors.(k) ;
|
|
draw_circle !i !j r;
|
|
coords.(k) <- (!i, !j)
|
|
done ;
|
|
|
|
for k = 0 to n-1 do
|
|
set_color colors.(k) ;
|
|
for l = 0 to (Array.length g.(k))-1 do
|
|
draw_poly_line [|coords.(k); coords.(g.(k).(l))|];
|
|
done
|
|
done;
|
|
|
|
set_line_width 22 ;
|
|
for k = 0 to n-1 do
|
|
set_color colors.(k) ;
|
|
for l = 0 to (Array.length g.(k))-1 do
|
|
let slope = Float.atan2 (float_of_int (snd coords.(g.(k).(l)) - snd coords.(k))) (float_of_int (fst coords.(g.(k).(l)) - fst coords.(k))) in
|
|
|
|
let nexi = int_of_float (float_of_int (fst coords.(k)) +. (float_of_int r) *. 1.5 *. cos slope) in
|
|
let nexj = int_of_float (float_of_int (snd coords.(k)) +. (float_of_int r) *. 1.5 *. sin slope) in
|
|
draw_poly_line [|coords.(k); (nexi, nexj)|]
|
|
done
|
|
done;
|
|
|
|
for k = 0 to n-1 do
|
|
set_line_width 10 ;
|
|
set_color black ;
|
|
fill_circle (fst coords.(k)) (snd coords.(k)) r;
|
|
set_color colors.(k) ;
|
|
set_line_width 5 ;
|
|
draw_integer (fst coords.(k)) (snd coords.(k)) k r
|
|
done;
|
|
|
|
ignore (Scanf.bscanf Scanf.Scanning.stdin "%d\n" identity) ;;
|
|
|
|
|
|
(* ----------------------- Tests --------------------------- *)
|
|
|
|
open_graph " 1200x800" ;;
|
|
set_window_title "Graphs" ;;
|
|
|
|
let gr = [|[|3; 5; 7|]; [|0|]; [|1; 7; 8|]; [|2; 6|]; [|0; 1; 3|]; [|6; 7|]; [|0; 1; 2|]; [|8|]; [|0; 7; 6|]; [||]; [||]; [|9|]|] ;;
|
|
|
|
improved_pretty_printing gr 1200 800 50 ;;
|
|
|
|
close_graph () ;; |