使用jquery在主要浏览器之间排序坐标点之间的差异

时间:2013-05-20 23:33:37

标签: jquery html5 cross-browser coordinates

在我正在开发的Web应用程序中,我正在检测某些图像的边界并沿检测到的边界生成一系列坐标点。由于生成数组的方式,不保证坐标点具有任何特定顺序。我写了一个比较器函数,它计算从中心点到任意两个给定点的矢量的叉积,以确定相对位置。这在chrome中运行良好,但是在firefox 21.0和IE 10中,一些坐标点没有正确排序。

比较器功能和排序功能的代码如下:

function sortCounterClockwise(a, b) {
    return ((isALeftOfB(a, b)) ? 1 : -1);
    //return ((isALeftOfB(a, b)) ? 1 : ((isALeftOfB(b, a)) ? -1 : 0));
}

function isALeftOfB(a, b) {
    var det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y);
    if (det < 0) {
        return false;
    } else if (det > 0) {
        return true;
    }

    var d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
    var d2 = (b.x - center.x) * (b.x - center.x) + (b.y - center.y) * (b.y - center.y);
    return d1 < d2;
}

我在http://jsfiddle.net/Zsz3K/1/创建了一个完整的工作jsfiddle,如果你在Chrome中查看它,你会看到蒙大拿州的正确粗略轮廓,但在FF和IE中它会混淆坐标点

我已尝试过上述算法的多种变体,但我无法在FF或IE中的所有测试用例中使用它,只有chrome。在之前的迭代中,我将一个点固定为参考点,认为IE和FF因排序的循环性质而被绊倒。我的测试用例是上传美国地图,chrome能够成功检测并正确跟踪所有边框。我无法更改程序以保证坐标数组通过从中心点增加或减少θ来排序,并且确实需要找到一致的方法来对这些坐标进行排序,这些坐标在此处列出的浏览器中正常工作。据我所知,这似乎是FF和IE中的一个错误,因为结果是基于数学结果,这些结果应该是跨浏览器不可变的。

编辑:将答案移至答案。

1 个答案:

答案 0 :(得分:0)

我已经创建了对jsfiddle的更新,我想这是一个模糊的回答我自己的问题。 http://jsfiddle.net/Zsz3K/3/

我粗略地进行了快速冒泡排序,并在比较器函数中添加了关于中心点的相对位置的附加条件,并且它适用于所有3个浏览器。我想这就是说,FF和IE中的.sort()实现似乎并不能很好地处理这类数据。我希望我有时间潜入jquery胆量,但我没有。因此,如果其他人遇到在jquery中排序空间坐标的问题,不要依赖于内置的排序函数,尽管我会推荐比vanilla冒泡更有效的东西,除了概念验证之外的其他东西。奇怪的是,chrome不仅使用内置的.sort()和比较器一直工作,而且它不需要(实际上被绊倒)使用相对位置到中心作为排序标准。

只是为了满足链接到jsfiddle的代码要求,这里是工作排序和比较器。

do {
    swapped = false;
    for (var i=0; i < points.length-1; i++) {
        if (isALeftOfB(points[i + 1], points[i])) {
            var temp = points[i];
            points[i] = points[i+1];
            points[i+1] = temp;
            swapped = true;
        }
    }
} while (swapped);

function isALeftOfB(a, b) {
if (a.y <= center.y && b.y > center.y) {
        return true;
    } else if (a.y == center.y && b.y == center.y) {
        return a.x < b.x
    }
    var det = (a.x - center.x) * (b.y - center.y) - (b.x - center.x) * (a.y - center.y);
    if (det < 0) {
        return false;
    } else if (det > 0) {
        return true;
    }

    var d1 = (a.x - center.x) * (a.x - center.x) + (a.y - center.y) * (a.y - center.y);
    var d2 = (b.x - center.x) * (b.x - center.x) + (b.y - center.y) * (b.y - center.y);
    return d1 < d2;
}