turf icon indicating copy to clipboard operation
turf copied to clipboard

`lineSplit` doesn't detect all intersections with curved lines

Open ianstormtaylor opened this issue 2 years ago • 2 comments

Running into a strange bug, but it reproduces reliably. When I have straight lines intersecting a circle, all of the intersections are detected no problem, but when the lines are curved (in this case with a Math.sin) Turf doesn't properly catch all the intersections.

Here's an example with straight lines:

image

And here's the same thing with curvy lines (with misses in red):

image

Here's a p5.js playground link which reproduces the bug in the latest version (6.X) of Turf.

If you change the size of the canvas, the misses change… some sizes have no errors (eg. 400x400) or some have just one (eg. 450x450) or some have many errors (eg. 500x500). It makes me think it has something to do with float-based arithmetic? But that's just a random guess.

What's going on here?

ianstormtaylor avatar May 11 '22 20:05 ianstormtaylor

I also have similar issue. Here is two geojson objects that should return 3 line segments but it only returns 2

{
"type": "FeatureCollection",
"features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [
                        -122.784210824,
                        38.46577859000006,
                        0
                    ],
                    [
                        -122.783497375,
                        38.46577665500005,
                        0
                    ],
                    [
                        -122.78349775899989,
                        38.46574340700003,
                        0
                    ],
                    [
                        -122.78337219700002,
                        38.46574404700004,
                        0
                    ],
                    [
                        -122.7833724819999,
                        38.46570876200008,
                        0
                    ],
                    [
                        -122.783186362,
                        38.46571185100002,
                        0
                    ],
                    [
                        -122.78318417300001,
                        38.46569283300004,
                        0
                    ],
                    [
                        -122.782172859,
                        38.46568571000005,
                        0
                    ],
                    [
                        -122.7821622549999,
                        38.46587288700003,
                        0
                    ],
                    [
                        -122.783391339,
                        38.465877436,
                        0
                    ],
                    [
                        -122.78339171499998,
                        38.46589273900003,
                        0
                    ],
                    [
                        -122.78420487999992,
                        38.46590174800005,
                        0
                    ],
                    [
                        -122.784210824,
                        38.46577859000006,
                        0
                    ]
                ]
            ]
        }
    },{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -122.7779211637529,
                    38.46929673131614
                ],
                [
                    -122.78647173567292,
                    38.46208580491829
                ]
            ]
        }
    }]
}

am2222 avatar May 13 '22 00:05 am2222

Another example.

{
"type": "FeatureCollection",
"features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -122.78875947237302,
                    38.4531482960872
                ],
                [
                    -122.77264018036279,
                    38.4664873022484
                ]
            ]
        }
    },{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [
                        -122.782651928,
                        38.459936152000076,
                        0
                    ],
                    [
                        -122.77997154699989,
                        38.459918425000076,
                        0
                    ],
                    [
                        -122.7799128509999,
                        38.45996424500003,
                        0
                    ],
                    [
                        -122.779876771,
                        38.46173445800007,
                        0
                    ],
                    [
                        -122.77987919199998,
                        38.46175493400005,
                        0
                    ],
                    [
                        -122.779909089,
                        38.461776498000056,
                        0
                    ],
                    [
                        -122.779936965,
                        38.46177923800009,
                        0
                    ],
                    [
                        -122.78026350800002,
                        38.4617772600001,
                        0
                    ],
                    [
                        -122.780357053,
                        38.46170124900002,
                        0
                    ],
                    [
                        -122.780371475,
                        38.46171235700007,
                        0
                    ],
                    [
                        -122.7804015899999,
                        38.46168883400004,
                        0
                    ],
                    [
                        -122.78043120300002,
                        38.46171220200007,
                        0
                    ],
                    [
                        -122.782651928,
                        38.459936152000076,
                        0
                    ]
                ]
            ]
        }
    }]
}

The underlying lineIntersect is returning the correct set of points

{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-122.78057341661047,38.45992240553217]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[-122.77990238599092,38.46047769552646]}}

if I use this function it gives me the correct set of lines https://github.com/Turfjs/turf-line-slice-at-intersection/blob/0af979fe5401de68d96dbb2cac0a21c57904c55a/index.js#L186

am2222 avatar May 13 '22 01:05 am2222