在 R 中沿直线的点和曲线之间绘制一条垂线

时间:2021-04-06 10:09:32

标签: r math geometry curve

我希望在 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 坐标。我不知道这是如何完成的。

enter image description here

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

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

最终,我想获得一个值,即图像中虚线的距离除以垂直线的长度。

请原谅我对数学的无知

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

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

enter image description here

1 个答案:

答案 0 :(得分:1)

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()

Output plot