计算曲线和直线之间的区域而不查找函数

时间:2018-02-12 17:19:39

标签: r

我在2D空间(A和B)中有两个点,并且曲线以A开始并以B结尾。我没有该曲线的函数,而是该曲线上的n个点的数组。

我希望计算假想线AB和曲线之间锁定的区域。

如果在R中如何做到这一点的任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

以下是使用pracma包的一种方法:

library(pracma)
trapz( c(data[1,2], tail(data[,2])), c(data[1,1],tail(data[,1])) ) - 
     trapz(data[,2], data[,1])

[1] 4276.685

trapz函数查找一组点下的区域。第一个trapz找到AB行下面的区域,并减去第二个trapz(点集下面的区域)。

答案 1 :(得分:2)

使用包的解决方案。假设dat是数据帧。如果您有矩阵,请从第二步开始。我们的想法是创建一个多边形,然后计算面积。

library(sf)

# Convert to matrix
dat_m <- as.matrix(dat)
# Repeat the first row
dat_m <- rbind(dat_m, dat_m[1, ])
# Convert to polygon
dat_pl <- st_polygon(list(dat_m))
# Calculate the area
st_area(dat_pl)
# [1] 4874

顺便说一下,这是多边形的样子。

plot(dat_pl)

enter image description here

数据

dat <- read.table(text = "-1416.7 214.7
-1418.4 216.8
                  -1420.3 219.2
                  -1422.2 221.8
                  -1424.2 224.5
                  -1426.3 227.5
                  -1428.4 230.6
                  -1430.3 233.9
                  -1432.2 237.3
                  -1434   241
                  -1435.6 244.8
                  -1437   248.7
                  -1438.4 252.8
                  -1439.5 257.1
                  -1440.5 261.4
                  -1441.2 265.8
                  -1441.8 270.4
                  -1442.2 274.9
                  -1442.4 279.5
                  -1442.5 284.1
                  -1442.4 288.8
                  -1442.1 293.5
                  -1441.8 298.3
                  -1441.4 303.2
                  -1441   308.2
                  -1440.6 313.3
                  -1440.4 318.3
                  -1440.1 323.3
                  -1439.9 328.2
                  -1439.7 333.1
                  -1439.4 338
                  -1439.1 342.8
                  -1438.6 347.6
                  -1438.1 352.4
                  -1437.4 357.1
                  -1436.7 361.8
                  -1435.8 366.4
                  -1435   371
                  -1434   375.5
                  -1433   379.9
                  -1432   384.3
                  -1430.9 388.7
                  -1429.9 392.9
                  -1428.8 397.2
                  -1427.8 401.3
                  -1426.8 405.4
                  -1425.9 409.4
                  -1425.2 413.2
                  -1424.7 416.8
                  -1424.3 420.2
                  -1424   423.4
                  -1423.8 426.4
                  -1423.7 429.3
                  -1423.7 432
                  -1423.8 434.6
                  -1423.9 437.1
                  -1424   439.5
                  -1424.1 441.8
                  -1424.2 444
                  -1424.2 446.2
                  -1424   448.3
                  -1423.8 450.3
                  -1423.4 452.3
                  -1423   454.3
                  -1422.4 456.1
                  -1421.9 457.9
                  -1421.4 459.6
                  -1420.9 461.2
                  -1420.5 462.8
                  -1420.1 464.3
                  -1419.8 465.6
                  -1419.6 466.9
                  -1419.3 468.1
                  -1419   469.2
                  -1418.6 470.2
                  -1418.2 471.2
                  -1417.7 472.1
                  -1417.2 473
                  -1416.6 473.8
                  -1415.9 474.5
                  -1415.2 475.2
                  -1414.2 475.8
                  -1413.2 476.4
                  -1412.2 476.9
                  -1411.3 477.3")

答案 2 :(得分:2)

您可以在没有任何包的情况下执行此操作。

以下是一些示例数据。

set.seed(2018)
x = sort(runif(150, 0,2))
y = sin(x) + sin(10*x)/20

我们可以从第一个点(x [1])到最后一个点(x [150])获得该区域。 Sample function

但是曲线之间的区域只是上面曲线下方的面积减去线下面积。您可以将approxfun与数据结合使用,以获得与上层函数的良好近似。然后只做积分。

## Find the line
m = (y[150] - y[1]) / (x[150] - x[1]) 
b = y[1] - m * x[1]

## Get the functions and compute the integrals.
F1 = approxfun(x,y)
F2 = function(x) { m*x+b }
integrate(F1, x[1], x[150])$value - integrate(F2, x[1], x[150])$value
[1] 0.4539384

答案 3 :(得分:2)

这是sp:

的方法
library(sp)
Polygon(r)@area
#4874

数据:

dput(r)
structure(list(V1 = c(-1416.7, -1418.4, -1420.3, -1422.2, -1424.2, 
-1426.3, -1428.4, -1430.3, -1432.2, -1434, -1435.6, -1437, -1438.4, 
-1439.5, -1440.5, -1441.2, -1441.8, -1442.2, -1442.4, -1442.5, 
-1442.4, -1442.1, -1441.8, -1441.4, -1441, -1440.6, -1440.4, 
-1440.1, -1439.9, -1439.7, -1439.4, -1439.1, -1438.6, -1438.1, 
-1437.4, -1436.7, -1435.8, -1435, -1434, -1433, -1432, -1430.9, 
-1429.9, -1428.8, -1427.8, -1426.8, -1425.9, -1425.2, -1424.7, 
-1424.3, -1424, -1423.8, -1423.7, -1423.7, -1423.8, -1423.9, 
-1424, -1424.1, -1424.2, -1424.2, -1424, -1423.8, -1423.4, -1423, 
-1422.4, -1421.9, -1421.4, -1420.9, -1420.5, -1420.1, -1419.8, 
-1419.6, -1419.3, -1419, -1418.6, -1418.2, -1417.7, -1417.2, 
-1416.6, -1415.9, -1415.2, -1414.2, -1413.2, -1412.2, -1411.3
), V2 = c(214.7, 216.8, 219.2, 221.8, 224.5, 227.5, 230.6, 233.9, 
237.3, 241, 244.8, 248.7, 252.8, 257.1, 261.4, 265.8, 270.4, 
274.9, 279.5, 284.1, 288.8, 293.5, 298.3, 303.2, 308.2, 313.3, 
318.3, 323.3, 328.2, 333.1, 338, 342.8, 347.6, 352.4, 357.1, 
361.8, 366.4, 371, 375.5, 379.9, 384.3, 388.7, 392.9, 397.2, 
401.3, 405.4, 409.4, 413.2, 416.8, 420.2, 423.4, 426.4, 429.3, 
432, 434.6, 437.1, 439.5, 441.8, 444, 446.2, 448.3, 450.3, 452.3, 
454.3, 456.1, 457.9, 459.6, 461.2, 462.8, 464.3, 465.6, 466.9, 
468.1, 469.2, 470.2, 471.2, 472.1, 473, 473.8, 474.5, 475.2, 
475.8, 476.4, 476.9, 477.3)), .Names = c("V1", "V2"), class = "data.frame", row.names = c(NA, 
-85L))