【问题标题】:Calculating the area between a curve and a straight line without finding the function在没有找到函数的情况下计算曲线和直线之间的面积
【发布时间】:2018-02-12 17:19:39
【问题描述】:

我在 2D 空间中有两个点(A 和 B)和一条从 A 开始到 B 结束的曲线。我没有该曲线的功能,而是该曲线上的 n 个点的数组。

我想计算假想线 AB 和曲线之间的锁定面积。

任何有关如何在 R 中执行此操作的帮助将不胜感激。

【问题讨论】:

  • 如果您可以分享一些示例数据集以便人们研究您的问题,那就太好了。
  • 这里是一个示例数据集的链接:link 第一个和最后一个点是 A 和 B。
  • approxfun逼近函数,然后用integrate求面积
  • 寻求帮助时,您应该包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出。

标签: r


【解决方案1】:

使用 包的解决方案。假设 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)

数据

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】:

    这是使用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,即点集下方的区域。

    【讨论】:

      【解决方案3】:

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

      这是一些示例数据。

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

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

      但是曲线之间的面积只是上面曲线下的面积减去线下的面积。您可以将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
      

      【讨论】:

        【解决方案4】:

        这是一种使用 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))
        

        【讨论】:

        • @www Polygon 函数从坐标的两列数字矩阵(在 dput 中给出)创建一个多边形。此对象的插槽area 包含该区域。
        猜你喜欢
        • 2019-02-07
        • 2017-10-12
        • 2011-06-24
        • 2017-10-12
        • 2016-11-20
        相关资源
        最近更新 更多