如何确定一个点是在连接 R 中各点的直线上方还是下方?

How to determine if a point is above or below a line connecting points in R?

Objective:

Given a set of data, how can I determine if a new data point is above or below the line connecting the points.

例如,如何确定显示的红点是在线上方还是在线下方(无需目测)?

我想用一条精确的线来拟合这些点。本质上是连接点,并且需要拟合才能使用线上的任何点作为比较器。

当前尝试:

So far I've tried fitting various splines to the data, but it is still a bit too smooth. I'm really looking for an exact fit to the data, sharp corners and all.

我试过自然样条曲线(以及 smooth.splines),但不能完全适应 exact/sharp:

plot(df$lowerx, df$lowery, type='b', xlab='x', ylab='y', pch=21, bg='steel blue')
myspline <- splinefun(df$lowerx, df$lowery, method='natural')
curve(myspline, add=T, from = 0, to=140, n = 100, col='green')

我认为一旦我得到正确的拟合,就可以直接使用它来确定点是在线上方还是线下方(例如使用预测或函数),但我需要有关拟合的帮助。

也完全欢迎另一种方法。

数据:

df <- structure(list(lowerx = c(11.791, 18.073, 23.833, 35.875, 39.638, 44.153, 59.206, 71.498, 83.289, 95.091, 119.676, 131.467, 143.76), lowery = c(5.205, 5.89, 6.233, 9.041, 10, 10.342, 12.603, 13.493, 14.658, 15.274, 15.89, 15.616, 15.342)), .Names = c("lowerx", "lowery"), class = "data.frame", row.names = c(NA, -13L))

这个post展示了如何做到这一点:How to tell whether a point is to the right or left side of a line

position为+1表示点在上面,-1表示点在下面,0表示直接在直线上,不需要拟合,只需要知道指的是哪两个点跨越行...

应用于您的示例:

df <- structure(list(lowerx = c(11.791, 18.073, 23.833, 35.875, 39.638, 44.153, 59.206, 71.498, 83.289, 95.091, 119.676, 131.467, 143.76), lowery = c(5.205, 5.89, 6.233, 9.041, 10, 10.342, 12.603, 13.493, 14.658, 15.274, 15.89, 15.616, 15.342)), .Names = c("lowerx", "lowery"), class = "data.frame", row.names = c(NA, -15L))

X <- 79
Y <- 13
xIndex2 <- which(df$lowerx > X)[1]
xIndex1 <- xIndex2 - 1
Ax <- df$lowerx[xIndex1]
Ay <- df$lowery[xIndex1]
Bx <- df$lowerx[xIndex2]
By <- df$lowery[xIndex2]
position = sign((Bx - Ax) * (Y - Ay) - (By - Ay) * (X - Ax))

R 函数 approxfun 将创建一个执行线性插值的函数。

> F <- approxfun(x=df$lowerx, y=df$lowery)
> F(80) > 13
[1] TRUE

我使用了您提供的数据并测试了我对 "red point" 坐标的最佳猜测为 (80, 13),所以它说 13 小于插值,而 (80,15) 是以上:

> F(80) > 15
[1] FALSE