两组x和y坐标之间的总面积[r]

时间:2018-03-02 14:06:24

标签: r

我有两个轨迹的一系列x和y坐标,现在我想能够计算线之间的空间面积。

以下是我正在使用的一个真实示例,试图捕捉用户所做的球线的偏差:

Real example

我通常会说要捕捉用户的线偏离球线的程度。我想要捕捉的方式是两条线之间的区域(尽管可以说最好的方法是捕捉用户线的每个点与球线的最小距离)。

我有一些代码可以通过简单的示例捕获该区域:

example.matrix = matrix(c(0,1,2,3,4,5,6,  2,5,3,5,3,5,2,  2,2,4,6,4,2,2),nrow = 7)
example.plot.data = data.frame(x = rep(example.matrix[,1],2),
                 ball_user = c(rep("user",length(example.matrix[,2])),
                               rep("ball",length(example.matrix[,3]))),
                 y_axis    = c(example.matrix[,2],example.matrix[,3]))

example.plot <- ggplot(example.plot.data, aes(x=x, y=y_axis, color=ball_user)) + geom_line()    
example.plot

生成以下图表:

Simple example

我可以用它来分析它(我相信):

area_under_curve = 0
for(x in min(example.matrix[,1]):max(example.matrix[,1])){
  indexes = example.matrix[,1]==x
  y.diff.array  = example.matrix[,2][indexes] - example.matrix[,3][indexes]
  pos.dif.array = y.diff.array[y.diff.array>0] 
  neg.dif.array = y.diff.array[y.diff.array<0] 
  if(length(pos.dif.array)==1){
    area_under_curve = area_under_curve + abs(pos.dif.array)
  } else {
    ## deal with overlap here
  }
  if(length(neg.dif.array)==1){
    area_under_curve = area_under_curve + abs(neg.dif.array)
  } else {
    ## deal with overlap here
  }
}

然而,正如我在上面的代码中强调的那样,如果这些行重叠,我没有解决方案,但是我认为我可以将代码置于我目前所拥有的框架中。例如,让我们假设我创建了一个图:

example.matrix = matrix(c(0,1,2,3,2,3,4, 2,5,4,5,4,5,3, 2,2,4,6,3,2,3),nrow = 7)
example.plot.data = data.frame(x = rep(example.matrix[,1],2),
                 ball_user = c(rep("user",length(example.matrix[,2])),
                               rep("ball",length(example.matrix[,3]))),
                 y_axis    = c(example.matrix[,2],example.matrix[,3]))

 example.plot <- ggplot(example.plot.data, aes(x=x, y=y_axis, color=ball_user,  group = ball_user)) + geom_point()+geom_path()
 example.plot

产生

enter image description here

我的公式对此不起作用。我的问题是,不知道球或用户线有多少次会自行备份。

我还怀疑我的计算简单图形线之间区域的解决方案是不必要的,所以可能有一个更优雅的解决方案,也解决了我复杂的例子?

或者,也许有一种方法可以从球的线上捕捉用户线中每个点的平均距离?我担心这需要从球的线上单独计算用户线上每个点的最短距离,因此在计算上要求很高。

2 个答案:

答案 0 :(得分:2)

这是一个解决方案,取决于你想要保持差异的标志。它使用了相同x - 值的测量结果,并将其与计算曲线下面积的auc包中的MESS函数相结合。

example.matrix = matrix(c(0,1,2,3,4,5,6,  2,5,3,5,3,5,2,  2,2,4,6,4,2,2),nrow = 7)
x <- example.matrix[,1]
y1 <- example.matrix[,2]
y2 <- example.matrix[,3]

MESS::auc(x, y1-y2)

给你一个结果3.如果你想要总面积(即扔掉标志)你可以使用

MESS::auc(x, y1-y2, absolutearea=TRUE)

给出了15.

答案 1 :(得分:2)

为了计算球与用户的偏差,我认为最合适的是计算每个时间步长的两条线的距离,然后取所有距离的平均值。

距离的计算实际上并不那么复杂:

calc_distances <- function(ball_x, ball_y, user_x, user_y) {
  sqrt((ball_x - user_x)^2 + (ball_y - user_y)^2) 
}

让我们试试你的例子吧。首先是简易版:

ball_x <- c(0,1,2,3,4,5,6)
ball_y <- c(2,2,4,6,4,2,2)
user_x <- c(0,1,2,3,4,5,6)
user_y <- c(2,5,3,5,3,5,2)

distances <- calc_distances(ball_x, ball_y, user_x, user_y)

par(mfrow=c(2,1))
plot(ball_x, ball_y, type = 'l', col = "red")
lines(user_x, user_y, col = "blue")
plot(distances, type = 'l')
abline(h=mean(distances), col = "red", lty = 2)

first example

更复杂:

ball_x <- c(0,1,2,3,2,3,4)
ball_y <- c(2,2,4,6,3,2,3)
user_x <- c(0,1,2,3,2,3,4)
user_y <- c(2,5,4,5,4,5,3)

distances <- calc_distances(ball_x, ball_y, user_x, user_y)

par(mfrow=c(2,1))
plot(ball_x, ball_y, type = 'l', col = "red")
lines(user_x, user_y, col = "blue")
plot(distances, type = 'l')
abline(h=mean(distances), col = "red", lty = 2)

second example