Search code examples
rarea

Area between two set of xy points with different x values


I am really struggling trying to find the total area (regardless positive or negative) between two vehicle trajectories in the form of sets of xy points with different x values and different number of points for each trajectory. I have tried the built-in integrate function; I tried to use built-in approximating function of (x1,y2-y1) and taking the absolute values and then integrate it but this not possible since the length of y1 and y2 is different in my case and the x values are not the same for each trajectory (I have x1 and x2)! I also tried AUC (area under curve) function (AUC(x1,abs(y2-y1))) in different packages like "MESS" and "DescTools" to find this area which works but not for my case again for the same reasons (different vector length and different x values). At the end, I found a function called "CreateMap" in pathmapping package which is absolutely awesome and compute the total area between two trajectories but only one problem that I can't define the x-range that I would like to compute the area within (it computes the area shown in the second figure below, whereas I would like to compute the area shown in the first figure), so I can't see any arguments in this function that allow you to determine x-range or from which point to which point you would like to compute the area within.

Here is an example:

library("pathmapping")
x1<-c(1,3,5,9,13,14,16,18,23)
y1<-c(8,8,10,10,6,7,4,5,5)
x2<-c(3,6,7,11,11,15,18)
y2<-c(7.5,7.5,11,11,4.5,4.5,10)
path1<-cbind(x1,y1)
path2<-cbind(x2,y2)
CreateMap(path1,path2,F)

Here is a figure that shows the needed shaded area: enter image description here I can find this shaded area using CreateMap function: enter image description here So basically I would like to calculate the area between two trajectories bounded by the internal/nearest start/end points of the two trajectories (as in the first figure). I can determine the boundaries but can't find a way to include them in CreateMap function.

To sum up, I need to compute the area shaded in the first figure above, I have two situations: 1. built in integrate function and AUC function in MESS and DescTools packages where I can't compute the area at all since I have different trajectory length (in the example above first one has 9 points while the second has 7) and different x values for each trajectory (path1 has x1, path2 has x2), although it is possible to include the x-range or boundaries in the mentioned functions. 2. CreateMap function in pathmapping package which compute the area (in figure 2) perfectly but can't determine or include boundaries in the function as I would like to compute the area between the trajectories only between the nearest pair of the trajectories start/end points (as in figure 1)

Any suggestions/hints with codes or functions (if possible) would be highly appreciated


Solution

  • Your functions are piecewise linear, so it would be possible to define functions through linear interpolation and to calculate the area by applying the known integration procedure.

    I will split your second function into two because at x = 11 it has two different values (which is not possible for functions).

    x1<-c(1,3,5,9,13,14,16,18,23)
    y1<-c(8,8,10,10,6,7,4,5,5)
    x2<-c(3,6,7,11)
    y2<-c(7.5,7.5,11,11)
    x3<-c(11,15,18)
    y3<-c(4.5,4.5,10)
    
    f1 <- approxfun(x1, y1, method = "linear", 1, 23)
    f2 <- approxfun(x2, y2, method = "linear", 3, 11)
    f3 <- approxfun(x3, y3, method = "linear", 11, 18)
    

    Now we integrate f1-f2 from 3 to 11 and f1-f3 from 11 to 18, and then add these two integral values.

    I1 <- integrate(function(x) f1(x) - f2(x), 3, 11)$value
    I2 <- integrate(function(x) f1(x) - f3(x), 11, 18)$value
    I1 + I2
    ## [1] 1
    

    If you want to avoid splitting functions, the following approach may also be possible.

    x1<-c(1,3,5,9,13,14,16,18,23)
    y1<-c(8,8,10,10,6,7,4,5,5)
    x2<-c(3,6,7,11-1e-15, 11+1e-15, 15, 18)
    y2<-c(7.5,7.5,11,11,4.5,4.5,10)
    
    f1 <- approxfun(x1, y1, method = "linear", 1, 23)
    f2 <- approxfun(x2, y2, method = "linear", 3, 18)
    
    integrate(function(x) f1(x)-f2(x), 3, 18)
    ## 1.000001 with absolute error < 3.3e-05
    

    To find all points where f1 is equal to f2, use findzeros() from the pracma package.

    pracma::findzeros(function(x) f1(x)-f2(x), 3, 18)
    [1]  6.714286 10.999927 15.300000
    

    We could now add the integrals from 3 to 6.7, from 6.7 to 11, from 11 to 15.3, and from 15.3 to 18 -- returning the same result (I hope).