locationtech / jts

The JTS Topology Suite is a Java library for creating and manipulating vector geometry.
Other
1.94k stars 442 forks source link

Why is Distance3DOp(g1,g2) and Distance3DOp(g2,g1) different? #585

Open radi2015 opened 4 years ago

radi2015 commented 4 years ago
        WKTReader wktReader=new WKTReader();
    String wkt1="LineString Z (13520263.3311040997505188 3654113.41769909998401999 14.55408463999999924," +
            " 13520263.98897077143192291 3654108.78580632992088795 14.56306395999999914," +
            " 13520265.05638116039335728 3654101.43723948998376727 14.5861752899999999)";
    String wkt2="LineString Z (13520262.04566529020667076 3654122.22497142991051078 14.53834022000000026, " +
            "13520263.19403318502008915 3654114.04906051000580192 14.55408463999999924)";
    GeometryFactory geometryFactory=new GeometryFactory();
    Geometry g1 = wktReader.read(wkt1);
    Geometry g2 = wktReader.read(wkt2);

    Distance3DOp distance3DOp1=new Distance3DOp(g1,g2);
    Coordinate[] coordinates1 = distance3DOp1.nearestPoints();
    System.out.println(geometryFactory.createPoint(coordinates1[0]).distance(
            geometryFactory.createPoint(coordinates1[1])));
    Distance3DOp distance3DOp2=new Distance3DOp(g2,g1);
    Coordinate[] coordinates2 = distance3DOp2.nearestPoints();
    System.out.println(geometryFactory.createPoint(coordinates2[0]).distance(
            geometryFactory.createPoint(coordinates2[1])));

out: 0.6460693969920951 5.322947522798961

dr-jts commented 4 years ago

This is indeed a bug. It looks like one of the CGAlgorithms3D distance algorithms is not symmetric. Not sure what the exact cause is yet.

takafimu-sukuzi commented 2 years ago

Hi. I`m using NetTopologySuite. It has same problem.

https://github.com/locationtech/jts/blob/539ef272f20507cfd666f5c219f9af150b593604/modules/core/src/main/java/org/locationtech/jts/algorithm/CGAlgorithms3D.java#L137-L144

In case s<0 && t<0, CGAlgorithms3D seems to compute only distancePointSegment(A, C, D). Does algorithm need to calculate distancePointSegment(C, A, B) in the case? s and t seem to be determined by the order of geometries. (g1,g2 / g2,g1)