HTML5 Augmented Reality: fuzzy results
I spent a few hours trying to figure out how to deal with the brand new deviceorientation API in order to obtain a nice Augmented Reality effect. First I searched on how to convert Euler Angles to Cartesian Coordinates and I found a nice article about that, then I downloaded the very nice Sylvester library which lets you compute matrix operations in Javascript.
Then I write this code:
Demo1 = function(){
var demo1 = {};
demo1.generatePoints = function(numero,dimensioni_box){
var points = [];
for(var i=0;i < numero; i++){
var x0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
y0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
z0 = Math.floor((Math.random()-0.5)*(dimensioni_box)),
x1 = x0 + 5;
y1 = x1 + 5;
z1 = z0;
points.push(
[$M([[x0],[y0],[z0]]), $M([[x1],[y1],[z1]])]
);
}
return points;
}
demo1.init = function(evento){
// #drawboard is a canvas element
demo1.canvas = document.querySelector('#drawboard');
demo1.canvas.width = 320;
demo1.canvas.height = 480;
demo1.context = demo1.canvas.getContext('2d');
demo1.points = demo1.generatePoints(200, 100);
};
demo1.resetCanvas = function(){
demo1.context.fillStyle = '#FFFFFF';
demo1.context.fillRect(0,0, demo1.canvas.width, demo1.canvas.height);
demo1.context.fillStyle = '#000000';
}
demo1.cambioOrientamento = function(evento){
demo1.resetCanvas();
var heading = ((evento.alpha > 180 ? evento.alpha - 360 : evento.alpha) * Math.PI) / 180.0;
var attitude = (evento.beta * Math.PI) / 180.0;
var bank = (evento.gamma * (Math.PI/2.0)) / 90.0;
var ch = Math.cos(heading), sh = Math.sin(heading),
ca = Math.cos(attitude), sa = Math.sin(attitude),
cb = Math.cos(bank), sb = Math.sin(bank);
var rotation_matrix = $M([
[ch*ca , -ch*sa*cb + sh*sb , ch*sa*sb + sh*cb ],
[sa , ca*cb , -ca*sb ],
[-sh*ca , sh*sa*cb + ch*sb , -sh*sa*sb + ch*cb ]
]);
for(var i=0; i < demo1.points.length; i++){
var pr = rotation_matrix.x(demo1.points[i][0]);
var x = 160 + ((640*pr.e(1,1)) / (pr.e(3,1)));
y = 240 - ((640*pr.e(2,1)) / (pr.e(3,1)));
demo1.context.fillRect(x,y,10,10);
}
};
return demo1;
}();
window.addEventListener('load',Demo1.init,false);
window.addEventListener('deviceorientation',Demo1.cambioOrientamento,false);
If you have a device which supports the deviceorientation API (eg: iPhone4) you can test the running example here: http://sandropaganotti.com/wp-content/goodies/mobile/demo1.html as you might notice is still far from perfect but at the moment I've no time to refine it and so I have to leave it 'as is' ( still somehow nice IMHO ).
If someone got a clues on this please e-mail me at: sandro.paganotti@gmail.com