代码之家  ›  专栏  ›  技术社区  ›  Eric

平面二维几何计算

  •  1
  • Eric  · 技术社区  · 8 年前

    我想做一些几何计算( 例如点到线的距离 )在二维平面上。

    目前正在调查 turfjs 计算点到线的距离。


    代码

    距离:JS:

    // hello
    var turf = require('@turf/turf')
    
    init();
    
    // init,
    function init() {
        distance();
    }
    
    function distance() {
        // line
        let line = turf.lineString([
        [0, 0],
        [3, 4]
        ]);
        console.log(line);
    
        // point
        let point = turf.point([3, 0]);
        console.log(point);
    
        // calculate distance from point to line, using planar,
        let dis = turf.pointToLineDistance(point, line, {
        units: 'degrees',
        method: 'planar'
        });
        console.log("distance: %f", dis);
    }
    

    产量

    距离:2.398995395932417

    如果我改为 [30, 0] 线到 [0, 0], [30, 40] ,则输出为:

    距离:25.741472914575986

    程序正在使用 degrees 作为单位,以及 planar 作为方法。

    预期的结果是 2.4 24 ,但事实并非如此。


    问题

    • 那么,这是否意味着这些点在曲面上,而不是平面上?
    • 是否可以在平面(而不是曲面)中定义点、线和多边形?
    • 如果没有,那么还有其他类似的工具来执行这个任务吗?
    2 回复  |  直到 8 年前
        1
  •  1
  •   nikoshr    8 年前

    如果你看看 turf.js source code for point to line distance ,您将看到它计算沿 rhumb line ,这不是平面几何中的预期。

    为了实现你想要的,你可以实现 equation 你自己,就像

    function pointToLineDistance(line, p0) {
        var p1 = line[0],
            p2 = line[1];
    
        var x0 = p0[0], y0 = p0[1],
            x1 = p1[0], y1 = p1[1],
            x2 = p2[0], y2 = p2[1]
    
    
        return Math.abs(
            (y2 - y1) * x0
            - (x2 - x1) * y0
            + x2 * y1
            - y2 * x1
        ) 
        /
        Math.sqrt(
            (y2 - y1) * (y2 - y1)
            +
            (x2 - x1) * (x2 - x1)
        );
    }
    
    console.log(
        pointToLineDistance([[0, 0], [3, 4]], [3, 0]),
        pointToLineDistance([[0, 0], [30, 40]], [30, 0]),
    );

    或者如果你喜欢图书馆 flatten.js 可以帮助你:

    let Flatten = require('flatten-js');
    
    let {point, line} = Flatten;
    
    let l = line(point(0, 0), point(3, 4));
    let p = point(3, 0)
    let d = p.distanceTo(l);
    
    console.log(d[0]);
    
        2
  •  1
  •   Stefano    8 年前

    Turf.js 本应用于墨卡托(网络,二维)地图,但对于计算,它基于 WSG84 (3d)标准,即认为地球是球体。但有时,特别是在广域上,二维地图上球面特征的表示和操作会返回不直观或意外的结果;在这些情况下,我们采用 Rhumb 甚至欧几里德运算(因此 planar 选择权 pointToLineDistance 例如),有时会导致精度降低。

    所以,要回答你的第一个问题,草皮会考虑你在曲面上的点,而要回答你的第二个问题,就不可能指示草皮在平面上工作。

    至于其他库,除了已经建议的 flatten.js 你可以看看 jsts 对于像并集和交集这样的操作。

    如果不局限于javascript,那么您可能需要查看python Shapely ,这在我看来是一个非常强大和可靠的工具。

    上述两个库都用于少数TURF包或用作实现和/或结果的参考。 关于…的笔记 JSTS ,它显示了 some issues 在草皮,但你可能会没事,这取决于你的案件的复杂性。