【问题标题】:Drawing a perpendicular line between a point along a line and a curve in R在沿线的点和R中的曲线之间绘制垂直线
【发布时间】:2021-07-02 02:52:54
【问题描述】:

我希望计算 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 工作)。

【问题讨论】:

  • 从您的中点到曲线,在与曲线的交点处垂直于曲线的线数不胜数。你的意思是你想要一条从点到曲线的垂直线?如果没有,你必须告诉我们如何识别你的线与曲线相交的点......
  • 对不起,是的。我正在尝试使用该方法的论文中的措辞。 (不清晰是我的,不是论文的)

标签: r math geometry curve


【解决方案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()

【讨论】:

  • 这与我正在寻找的非常接近,因为它给了我从中点开始的垂直线。但是,我需要一条考虑到虚线斜率的垂直线,所以我不清楚这一点,抱歉。不过,我将发布另一个编辑,因为我根本不清楚。不过,我真的很感谢您的回复!
  • @SLewis 希望这就是你现在所追求的
  • 谢谢你。它看起来正是我正在寻找的。我还有一个问题。我首先查看“曲线上与中点端点之间的线垂直的点”,但实际上我也想查看其他点 - 沿线的三分之一和两个三分之二的方式。有没有办法用 approx 函数来做到这一点?明天我会尝试这一切,看看它是否对我有用,如果它有效,我会将你的解决方案标记为已解决。谢谢!
  • 您可以通过计算或使用均值加权将mean(range(Curve$X, na.rm=TRUE)) 更改为沿途的不同比例
  • 嗨米夫。我已经发布了另一个与此相关的问题,我正在帮助你,asking how to embed this within a function