在不同浏览器中使用相同数学的不同结果

时间:2013-11-16 03:36:03

标签: javascript math v8 spidermonkey

编辑:由于Chrome已更新浏览器 - 这个问题是多余的,因为他们修复了内部错误,这意味着不再出现此问题。

我有一个固定在画布中心的圆圈动画。

圆圈越大,运动越不稳定。但不仅如此,对我来说至少在Chrome到Firefox中情况要差得多。

数学在这个函数中完成:

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);  
}

这是工作示例中的代码:

http://jsfiddle.net/96QDK/

Chrome输出:

Firefox输出:

enter image description here

Firefox似乎最接近我的目标,但Chrome只是古怪。

为什么我会得到如此不同的结果?我应该提到我已经问了几个人他们看到了什么,每个人都看到了不同的不准确度。

2 个答案:

答案 0 :(得分:28)

问题不在于Javascript数学;这是 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();
}

请注意,数字与完全相同与Firefox相同,但显然在Chrome中错误地绘制了红色弧。

screenshot

有趣的是,这适用于Math.PI / 4的倍数的所有角度,但是对于这些角度之间的值是关闭的(因此OP示例中的起伏行为)。

我已记录Chromium bug #320335

编辑:它看起来像是在2012年5月首次报道,并且是由Skia库中的错误引起的。

现在已经解决为fixed

答案 1 :(得分:2)

不会给你一个答案,但有趣的是Chrome上有数学问题

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

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

如果您将各个部分从Update()和draw()中变为变量,那么您可以使用

var current = i.currentAngle;
var delta = (deltaTime/1000 * i.rotationSpeed);

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

你打印出来(0.025和0)

如果你改为

var current = i.currentAngle;
var delta = (deltaTime/1000 * i.rotationSpeed);

i.currentAngle = current + delta;

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

你获得了巨大的价值。

但如果你这样做

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

然后newval的值大约为0.025,这正是您所期望的。

奇怪的是,如果你那么做以下

var newval = current + delta;
i.currentAngle = newval

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

然后newval现在是一个完全疯狂的价值....