简单的 st_intersect 示例给出了意想不到的结果

Simple st_intersect example gives unexpected result

我正在使用 R 中的 sf 包来模拟在 space 时间内在网络中的不同节点之间移动的代理样本。

我目前对 st_intersects 的一些行为感到困惑:我让代理在坐标单位正方形的每个角之间的节点之间移动,并穿过 (.5,.5) 的中心。但是,当我尝试在 st_point(c(.1,.9)) 处检测与几何 st_linestring(c(st_point(c(0,0)),st_point(c(0.5,0.5)))) 相交的代理时,我得到一个空谓词 return.

相反,如果我检测到代理仅沿 x 轴或 y 轴移动,我能够正确检测到该点。这是为什么?

R v4.0.2 中的最小可重现示例:

library(sf)

l1 <- st_linestring(c(st_point(c(0,1)),st_point(c(0.5,0.5))))
p1 <- st_point(c(.1,.9)) ## on the line between (0,1) and (.5,.5); y=1-x x = f(t)


st_intersects(p1,l1) ## empty
#Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
# 1: (empty)


## in contrast
l2 <- st_linestring(st_point(c(0,0)),st_point(c(1,0)))
p2 <- st_point(c(.1,0)) ## on the line between (0,0) and (1,0) ; y = 0; x = f(t)

st_intersects(p2,l2) ## returns 1 as I would expect
#Sparse geometry binary predicate list of length 1, where the predicate was `intersects'
# 1: 1

浮点几何本身就有缺陷。因此,您的结果很可能是由于您的实数的计算机表示不够精确。一种可能的解决方法是找到点和线之间的距离,如果距离小于某个阈值,则接受该点在线上。

详细说明 ege-rubak 的回答:这一点有微小的差异,很可能是由于浮点数学(本质上是不准确的)。

作为解决方法,我建议使用 sf::st_is_within_distance() 和足够小的 dist 值来消除舍入差异而不引入误报/可能需要根据所使用的数据进行一些调整。

考虑这段代码,最初发布在 RStudio 社区论坛上(这个问题似乎已经交叉发布):https://community.rstudio.com/t/simple-st-intersect-gives-unexpected-result/108214/3?u=jlacko

library(sf)
l1 <- st_linestring(c(st_point(c(0,1)),
                      st_point(c(0.5,0.5))))
p1 <- st_point(c(.1,.9)) ## on the line between (0,1) and (.5,.5); y=1-x x = f(t)

st_distance(l1, p1)[1,1]
# [1] 1.962616e-17

st_is_within_distance(p1,l1, 1/1000) 
# Sparse geometry binary predicate list of length 1, where the
# predicate was `is_within_distance'
# 1: 1