Archive for the visualization Category

Writing test-code

Posted in code, physics, visualization with tags , on August 11, 2010 by maxpower3141

One of the tasks, that in my knowledge is too often neglected (well you know I do this!), is writing test-code for new functionality.

Recently in my post on an O’Caml rant, I was complaining how O’Caml made it impossible for me to do the “simplest of all computer operations” – sleep. I simply wanted to make my CPU(s) idle for a while after drawing some visualization graphics, in order to produce a fluid animation, and it seemed hopeless. I just went on and implemented (the dreaded) busy-loop. 🙂

This test-case, even though it provided visual confirmation that my dynamic friction model (well the first option anyways – I have 2 others to check still) was ok, but it was lacking something important: Error analysis – the Final Frontier for programmers, where even the uber-nerds wont go without some serious recommending.

There are a few easy things we can check out in these sort of cases:

1) Distance from constraint manifolds (for both position and velocity variables)
2) Constraint force (I actually projected the total force vector to constraint-manifold normal. subtracted gravity before projection in order to measure directly the force felt by particle due to constraint)
3) Friction force (should depend linearly on the constraint force)

Computing these values turned out to be already a task, but visualizing them over time turned out even larger task – here’s the gif-animation:

Animating particle sliding on the sine curve

Of course the classical “O’Caml list-reverse” happened, so that the plot is like a polygraph, lie-detector type of curve (For me this happens all the time with O’Caml lists – and of course any iteration through the list inverts it! :))

But furthermore the results seem good, except one tiny thing: The friction force seems to diverge when going through zero-velocity of the particle – how very odd, no? I spent already some time verifying the math – it all matches, so what’s wrong? I know my friction model in this case is not perfect, but the discrepancy should not be so noticeable.

Well, the (yet again too obvious) solution was that this model had only implemented dynamical friction!

    Rest friction not yet implemented!!

. D’Oh! 🙂 The classical – without rest friction the plot is supposed to look something like that!!!

So well, moving on to implement rest friction and then to try the two other friction models! I’ll be back with more cool things! … Like more code… And physics.. and math.. and.. Uh.. Yeah – I know – super cool!Well, I am having a glass of wine while coding now, so, I guess I’m not completely hopeless, yet? Ok? And if I play a tad on my guitar?

🙂

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.