在R中沿直线的点和曲线绘制垂直线

Drawing a perpendicular line between a point along a line and a curve in R

我希望在 R 中计算一条线的中点和它上面的一条曲线之间的距离,但在数学上很密集。我的曲线看起来都像下面代码中显示的那样:

Curve <- data.frame(X = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 4.9046, 6.1424, 7.275, 8.5851, 10.0373, 11.9981, 13.7726, 15.0731,16.0664, 
18.1945, 21.2666, 24.2093, 26.7119, 28.8037, 30.7135, 32.1351,  33.1982, 34.2341, 35.7587, 37.2147, 38.4303, 39.625, 40.4596, 42.0938, 42.7428, 42.7593, 43.5085, 43.7419, 43.5989, 44.0841, NA, NA, NA), 
Y = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, -9.9938, -7.4596, -4.8647, -2.2903, 0.3158, 2.9302, 5.7262, 8.7033, 11.8007, 14.9847, 16.7225, 16.7813, 15.6921, 14.2964, 11.5579, 8.2378, 5.183, 1.5938, -2.0712, -5.195, -7.1447, -9.0446, -11.1269, -13.0979, -15.3295, -17.1898, -19.4376, -21.4781,-23.8426, -25.6343, NA, NA, NA),              
fan_line = 1:42)    

我能够在第一个和最后一个 xy 坐标之间画一条线,并找到该线的中点(如下图所示)。从这个中点开始,我现在需要构建一条从中点延伸到曲线的垂直线,并在该点提取 xy 坐标。我不知道这是怎么做到的。

如果相关的话,我所有的绘图都是在 ggplot 中完成的,但主要是我感兴趣的是提取垂直于图像中显示的中点(曲线的第一个和最后一个 xy 坐标之间的中点)的 XY 坐标,所以值而不是绘图本身。

我之前一直在根据中间 X 坐标(忽略 NA 值)计算曲线的中间 x 和 y 坐标,但这根本不是我想要的。

最终我有兴趣获得一个值,该值是图像中虚线的距离除以垂直线的长度。

请原谅我数学上的无知

编辑:正如 Limey 指出的那样,从一个点开始有任意数量的垂直线。我的意思是从中点沿着我画的虚线垂直。

Edit2:很抱歉不清楚我在找什么。基本上,我想最终基本上获得类似于下图中红线的东西(请原谅 Microsoft Paint 作业)。

approx() 函数允许您找到对应给定 x 坐标的 y 坐标,例如:

approx(Curve$X, Curve$Y, mean(range(Curve$X, na.rm=TRUE)) )
# $x
# [1] 24.49435
# 
# $y
# [1] 16.65724

然而,您似乎想要找到曲线上垂直于中点端点之间直线的点。为此,您可以通过连接端点的直线的梯度旋转曲线,使直线平坦,使用上述方法,然后沿相反方向旋转。执行此操作的代码是:

library(lava)

Ends <- Curve[Curve$X %in% range(Curve$X, na.rm=TRUE),]

theta <- atan(diff(Ends$Y)/diff(Ends$X))

rotCurve <- rotate2(as.matrix(Curve)[,1:2], theta)
rotEnds <- rotate2(as.matrix(Ends)[,1:2], theta)

rotPoint <- approx(rotCurve[,1], rotCurve[,2], mean(rotEnds[,1]) )

Point <- rotate2(matrix(c(rotPoint$x, rotPoint$y), ncol=2), -theta)
#         [,1]     [,2]
# [1,] 33.39819 4.490086

用一个快速绘图来验证它看起来像你的图表

ggplot() + geom_line(aes(x=X, y=Y), Curve) + geom_line(aes(x=X, y=Y), data=Ends, lty=2) + 
  geom_line(aes(x=c(mean(Ends$X), Point[1]), y=c(mean(Ends$Y),Point[2])), colour='red') + coord_equal()