如何避免大型地图中的数字精度问题?

时间:2019-05-17 11:00:40

标签: javascript d3.js

我从事的一个项目使用d3 SVG贴图作为现实场景的2D表示。我们的位置以米为单位。场景中的物体可以距0,0几百万米。我们使用d3的zoom.scaleExtent([0.01,100]),因此我们可以在屏幕上以100显示数十公里,而在0.01上则可以显示两十几米。当放大这些遥远的对象时,计算出的“ transform”属性难以精确地工作,并且对象和线点最终移位并最终从屏幕上完全消失。通常如何处理亚米级精度的大型场景,我该怎么做以减轻这些问题?

javascript的数字是正确的,但是计算出的CSS中的科学计数法使用较少的位。解析检查器中显示的变换值表明,与javascript输出的数字相比,我们的对象移位了数十米。我最终发现浏览器使用的计算值少于64位。实际上,这种精度存在两个问题:

1)位置差异随着点距原点的增加而增加,并且我们离物体越近(放大)

2)我们放大得越多,场景中SVG图片的大小就会开始跳动

我们使用SVG图像作为结构,并使用路径作为它们之间的直线。我尝试修改SVG图像大小,并将viewbox设置为较小,较大和圆形值。可以预见,这没有效果。将对象移到更靠近原点的位置可以缓解一些定位方面的精度问题,但是我们的结构SVG尺寸在更改缩放比例时会“抽搐”。大小应该是恒定的,但是每次重新计算缩放比例时,它们的大小应在更窄或更窄之间切换。

您可以在此处看到这两种方法的实际使用:https://i.imgur.com/nfjzmUi.png 红线应该是直线,点应该在其上,并且结构的显示大小与预期大小不同。我将鼠标悬停在检查器中的元素上,以显示蓝色的预期大小,我们的SVG图像紧密地放置在其视图框中,并且侧面不应有此透明填充。预期大小不会改变,但是在每个缩放级别上显示的大小都不同。大小通常不会改变,但是我们使用了自动缩放功能,该功能将当前缩放范围作为输入,并计算一个乘以图像缩放比例的因子,以便在所有缩放级别上保持恒定的屏幕尺寸。这将迫使尺寸重新计算并捕捉到新的(不正确的)尺寸。

这是我们更改/设置场景中元素位置的方式。相当标准的属性设置内容。

function move (node, delta) {

    // Transform is simply an object that parses the SVG's transform attribute into an object with properties (translate, scale, rotate, etc.)
    var transform = new Transform(node),
        // 
        position = {
            x: parseFloat(node.attr('x')),
            y: parseFloat(node.attr('y'))
        };

    transform.rotate.x += delta.x;
    transform.rotate.y += delta.y;

    node.attr('x', position.x + delta.x)
        .attr('y', position.y + delta.y)
        // converts the modified transform object back into a valid transform attribute string
        .attr('transform', transform.toString());
}

自动缩放功能很难读取并调用其他功能,但是已经过测试,无法保证,这也不是问题。即使关闭自动缩放,尺寸也不正确。这两个代码块都不重要,但是我已经包含了第一个,因此您可以根据需要检查自己。

说实话,我不确定100%的尺寸是怎么回事。任何帮助,将不胜感激。项目需求我们无法更改的是:zoom.scaleExtent的值(我们需要低缩放和高缩放)和结构的大小(svg图像)。

0 个答案:

没有答案