Archive for the code Category

Eclipse: Too many files open

Posted in code on August 4, 2010 by maxpower3141

How lovely it is when Linux (or possibly OpenSUSE) security model makes me lose changes by not letting me save a file from Eclipse. nice. Good going Linux. Not being able to save a file? How did we get here?

Advertisements

Ocaml strikes back

Posted in code, physics, visualization on August 4, 2010 by maxpower3141

Grr – I got angry with my trusty old O’Caml’s back again.

It all started with my hobby physics engine project (I’ll talk about this more at some later post*) that I’ve been putting together in my free time – I wanted to visualize how well my first draft of joint-friction works; Should be easy with a powerful language, no sweat, right? Well almost. 🙂

*) Actually now that I think about it, I’ll probably never dedicate a whole post to explaining it, but you, my loyal reader, can gather bits and pieces of it from various future posts, or something. 🙂

I already had most of the dummy code for my test-case written (point-particle on a sine-curve)

Parameters:

type state = { x : float; y : float; vx : float; vy : float; lambda : float };;
let h = 0.02;;
let g = 10.0;;
let mass = 1.0;;
let fricCoef1 = 0.1;;

Then some update code (manully solving the constraint equation for phi(x,y) = y + sin x = 0 etc. and then the fun part:

Visualizing the slide!

Grab google and O’Caml reference manual (http://caml.inria.fr/distrib/ocaml-3.09/ocaml-3.09-refman.pdf) and we have all we need:

(In case you are on Linux (more on that later 🙂 type something like ocaml graphics.cma to get the interpreter with X11 support)

Open Graphics module, create default window surface and resize it to (1024×768):

open Graphics;;
open_graph "";;
resize_window 1024 768;;

Then define starting point on window (lower right being 0,0!), with which factor to scale the gfx and draw the basic coordinate axles (x = 0 and y = 0)

let scale = 100.0;;
let x0 = 100;;
let y0 = 400;;


let drawAxis () =
set_color (rgb 0 0 0);
set_line_width 2;
moveto x0 10;
let w = size_x () in
let h = size_y () in
lineto x0 (h-11);
moveto 10 y0;
lineto (w -11) y0;
;;

Easy, no?

Then just define the functions needed to draw the sine-curve, then the whole background and ultimate the whole state:


let pixelcoordX x = x0 + int_of_float (scale *. x);;
let pixelcoordY y = y0 + int_of_float (scale *. y);;

let drawCurve () =
let nPoints = 50 in
set_color (rgb 120 120 120);
set_line_width 1;
let first = ref true in
for i = 0 to nPoints do
let x = -.0.7 +. (float_of_int i) *.
9.6 /. (float_of_int nPoints) in
let y = -.(sin x) in
let drawCall =
if !first then
moveto
else
lineto
in
drawCall (pixelcoordX x) (pixelcoordY y);
first := false
done;
;;


(* drawCurve ();; *)


let drawBackGround () =
clear_graph();
drawAxis();
drawCurve()
;;


let drawState state =
let x = state.x in
let y = state.y in
set_color (rgb 220 20 120);
set_line_width 3;
draw_circle (pixelcoordX x) (pixelcoordY y) 6
;;

Almost there! Only thing missing is some loop to render the frames – what this means, is that I need to just draw my graphics to the windowing-system backbuffer, post that to the frontbuffer and wait a while to get smooth animation – preferrably so that the the time used to compute physics step and draw the graphics is comparable to physics-stepsize.

But wait, there’s no sane way to wait in O’Caml!!! The Unix-module has wait-function for complete seconds only! So – I can’t wait 0.02 seconds which is my physics-stepsize. Unix-select could apparently also be used, but for some reason Unix.select [] [] [] 0.02 causes an exception (The system-call is pre-empted by an interrupt apparently). So what is the solution? Apparently there isn’t any? How is one supposed to code this thing? I mean, these are preeeettyyy basic OS-services that should be always available. Well – after googling and trying out desperate things for an hour or so, I deviced an elegant solution: The busy-loop – here we go:


let drawFrame state =
auto_synchronize false;
drawBackGround();
(* ignore (Unix.select [] [] [] 0.01); *)
(* ignore (Unix.sleep 1); *)
(*GRRRRRRRRRRRRRRRRRRRR OCAML SUCCCCCCCKKKKKSSSSSSSS!!!!!!! NO WAY TO
SLEEEEEEEEEEEEEEPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP!!!!!!!!!!!!!!!*)
for i = 1 to 90009 do (); done;
drawState state;
synchronize();
auto_synchronize true;
;;


let runNFrames n state =
let s = ref state in
for i = 0 to n do
drawFrame !s;
s := fricstep !s
done
;;


runNFrames 1000 s;;

Beautiful, isn’t it? Well, with this trickery I was able to play my smoooth animation and verify that visually the quality is ok and that the test-particle stops quite nicely to the bottom of the hill.