open Gphys (* a simple demo *) let width, height = (480, 340) (* Access to the canvas in the html document *) let canvas = Canvas.getElementById Canvas.document "my_canvas" let ctx = Canvas.getContext canvas "2d" let red = "#F00" let green = "#0F0" let blue = "#00F" let white = "#FFF" let black = "#000" let bg_color = blue let seg_color = white let circ_color = black let draw_circle color circle = Canvas.strokeStyle ctx color; Canvas.beginPath ctx; Canvas.lineWidth ctx 1.8; Canvas.arc ctx circle.cx circle.cy circle.r 0.0 6.28 false; Canvas.closePath ctx; Canvas.fill ctx; Canvas.stroke ctx; () ;; let draw_segment color segment = let p1, p2 = segment in let p1x, p1y = p1 in let p2x, p2y = p2 in Canvas.strokeStyle ctx color; Canvas.lineWidth ctx 1.4; Canvas.beginPath ctx; Canvas.moveTo ctx p1x p1y; Canvas.lineTo ctx p2x p2y; Canvas.closePath ctx; Canvas.stroke ctx; () ;; let display_demo circles segments = (* Fill the background *) Canvas.fillStyle ctx bg_color; Canvas.fillRect ctx 0 0 width height; (* Draw the circle *) List.iter (draw_circle circ_color) circles; (* Draw the segments *) List.iter (draw_segment seg_color) segments; () ;; (* Main *) let () = Random.self_init (); let circles = [ { cx = 100.0; cy = 50.0; r = 8.4; vx = 2.0; vy = 0.0; static = false; custom = () }; { cx = 30.0; cy = 10.0; r = 12.6; vx = -1.0; vy = 0.0; static = false; custom = () }; { cx = 60.0; cy = 20.0; r = 10.9; vx = 1.4; vy = 0.0; static = false; custom = () }; { cx = 80.0; cy = 50.0; r = 9.6; vx = -0.6; vy = 0.0; static = false; custom = () }; { cx = 120.0; cy = 30.0; r = 6.2; vx = 0.8; vy = 0.0; static = false; custom = () }; ] in let rand_circles = List.init 12 (fun _ -> { cx = 160.0 +. Random.float 320.0; cy = 10.0 +. Random.float 60.0; r = 4.0 +. Random.float 10.0; vx = 2.0 -. Random.float 4.0; vy = 0.0; static = false; custom = (); } ) in let circles = ref (circles @ rand_circles) in let segments = [ (10.0, 330.0), (470.0, 330.0); (* Horizontal segment *) (390.0, 210.0), (430.0, 210.0); ( 80.0, 180.0), (280.0, 220.0); (290.0, 300.0), (370.0, 270.0); ( 10.0, 330.0), ( 10.0, 120.0); (* Left *) (470.0, 330.0), (470.0, 120.0); (* Right *) ] in let gravity = 1.6 in (* Gravity *) let dt = 0.2 in let restitution = 0.8 in (* Coefficient of restitution (0.8 means 20% energy loss) *) (* Run the simulation *) let animate () = circles := update_circles !circles segments (0.0, gravity) dt restitution; display_demo !circles segments; () in let _ = Canvas.setInterval animate (1000/24) in () ;;