问题描述
我希望在 R 中计算一条线的中点与其上方的曲线之间的距离,但在数学上很密集。我的曲线看起来都像下面代码中显示的那样:
Curve <- data.frame(X = c(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),Y = c(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,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)[,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,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()