我有两个轨迹的一系列x和y坐标,现在我想能够计算线之间的空间面积。
以下是我正在使用的一个真实示例,试图捕捉用户所做的球线的偏差:
我通常会说要捕捉用户的线偏离球线的程度。我想要捕捉的方式是两条线之间的区域(尽管可以说最好的方法是捕捉用户线的每个点与球线的最小距离)。
我有一些代码可以通过简单的示例捕获该区域:
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
生成以下图表:
我可以用它来分析它(我相信):
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
产生
我的公式对此不起作用。我的问题是,不知道球或用户线有多少次会自行备份。
我还怀疑我的计算简单图形线之间区域的解决方案是不必要的,所以可能有一个更优雅的解决方案,也解决了我复杂的例子?
或者,也许有一种方法可以从球的线上捕捉用户线中每个点的平均距离?我担心这需要从球的线上单独计算用户线上每个点的最短距离,因此在计算上要求很高。
答案 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)
更复杂:
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)