Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different results using the same maths in different browsers

Edit: since chrome has updated the browser - this question is some what redundant as they have fixed an internal bug which means this problem no longer occurs.

I have an animation of a circle anchored to the center of the canvas.

The larger the circle becomes the less stable the motion is. But not only that, for me at least it is significantly worse in Chrome to Firefox.

The math is done in this function:

function update(deltaTime){     var centerX = canvas.width/2;     var centerY = canvas.height/2;         i.currentAngle = (i.currentAngle || 0) + (deltaTime/1000 * i.rotationSpeed);      if(i.currentAngle>2*Math.PI){         i.currentAngle-=2*Math.PI;     }         i.x = centerX + (i.radius*i.factor) * Math.cos(i.currentAngle);         i.y = centerY + (i.radius*i.factor) * Math.sin(i.currentAngle);   } 

This is the code in working example:

http://jsfiddle.net/96QDK/

Chrome outputs:

Firefox Outputs:

enter image description here

Firefox seems to be closest to what I am aiming for yet Chrome is just wacky.

Why do I get such different results? I should mention I've asked a few people what they see, and everyone is seeing different amounts of inaccuracy.

like image 629
Sir Avatar asked Nov 16 '13 03:11

Sir


People also ask

What does math do in JavaScript?

The math object provides you properties and methods for mathematical constants and functions. Unlike other global objects, Math is not a constructor. All the properties and methods of Math are static and can be called by using Math as an object without creating it.

Why is CSS different in Web browsers?

It look different because each browser has his own CSS style defined. This styles apply to the HTML markup when no other CSS is defined inline or comes from an external CSS file.


2 Answers

The problem is not with the Javascript math; it's with the canvas.

http://jsfiddle.net/LDWBX/

function bigCircle(angle) {     var radius = 5000; //the bigger, the worse     var x = canvas.width/2 + radius*Math.cos(angle);     var y = canvas.height/2 + radius*Math.sin(angle);      ctx.beginPath();     ctx.arc(x, y, radius, 0, 2 * Math.PI);     ctx.lineWidth = 2;     ctx.stroke(); } 

Notice that numbers appear exactly the same as in Firefox, but the red arc is obviously drawn incorrectly in Chrome.

screenshot

Interestingly, this works for all angles that are multiples of Math.PI / 4 but is off for values between those (hence the undulating behavior in the OP's example).

I've logged Chromium bug #320335.

EDIT: It looks like it was first reported in May 2012, and was caused by a bug in the Skia library.

It has now been resolved as fixed.

like image 150
Paul Draper Avatar answered Sep 30 '22 20:09

Paul Draper


Doesn't give you an answer, but Interestingly on Chrome there is a issue with the maths

i.currentAngle => 0.0; (deltaTime/1000 * i.rotationSpeed) = 0.025;  i.currentAngle + (deltaTime/1000 * i.rotationSpeed) = 2215385637.025; 

If you get the individual parts into variables out of Update() and into draw() so that you can use

var current = i.currentAngle; var delta = (deltaTime/1000 * i.rotationSpeed);  ctx.fillText(("angle == " + current+ " delta " + delta),10,50); 

you get (0.025 and 0) printed out

if you then change to

var current = i.currentAngle; var delta = (deltaTime/1000 * i.rotationSpeed);  i.currentAngle = current + delta;  ctx.fillText(("angle == " + i.currentAngle + " delta " + delta),10,50); 

You get a crazy large value.

but if you do

var newval = current + delta; ctx.fillText(("angle == " + newval + " delta " + delta),10,50); 

then newval has a value of around 0.025 which is what you would expect it to be.

Oddly if you then do the following

var newval = current + delta; i.currentAngle = newval  ctx.fillText(("angle == " + newval + " delta " + delta),10,50); 

then newval is now the completely crazy value....

like image 34
Code Uniquely Avatar answered Sep 30 '22 22:09

Code Uniquely