1

I have two points in a 2D space (A and B) and a curve that starts in A and ends in B. I don't have the function of that curve, but an array of n points on that curve.

I wish to calculate the area that is locked between the imaginary line AB, and the curve.

Any help on how to do that in R would be greatly appreciated.

G.N.
  • 139
  • 8
  • 2
    It would be great if you can share some example dataset so people can study your question. – www Feb 12 '18 at 17:26
  • Here is the link to an example dataset: [link](https://pastebin.com/gMxz3PBf) The first and last points are A and B. – G.N. Feb 12 '18 at 17:32
  • approximate the function using `approxfun`, and then use `integrate` to find the area – bouncyball Feb 12 '18 at 17:51
  • When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Feb 12 '18 at 19:36

4 Answers4

2

Here is one approach using the pracma package:

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

The trapz function finds area under a set of points. The first trapz finds the area under the AB line, and subtracts by the second trapz, the area under the set of points.

thc
  • 9,527
  • 1
  • 24
  • 39
2

A solution using the package. Assuming that dat is a data frame. If you have a matrix, please begin with the second step. The idea is to create a polygon and then calculate area.

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

By the way, here is how the polygon looks like.

plot(dat_pl)

enter image description here

DATA

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")
www
  • 38,575
  • 12
  • 48
  • 84
2

You can do this without any packages.

Here is some sample data.

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

We can get the area from the first point (x[ 1]) to the last (x[150]). Sample function

But the area between the curves is just the area under the upper curve minus the area under the line. You can use approxfun with your data to get a good approximation to the upper function. Then just do the integrals.

## 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
G5W
  • 36,531
  • 10
  • 47
  • 80
2

Here is an approach with sp:

library(sp)
Polygon(r)@area
#4874

data:

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))
missuse
  • 19,056
  • 3
  • 25
  • 47
  • @www the `Polygon` function creates a polygon from a two column numeric matrix of coordinates (given in dput). The slot `area` of this object contains the area. – missuse Feb 12 '18 at 18:16