【问题标题】:Calculating the area between shapes in R计算R中形状之间的面积
【发布时间】:2014-02-16 03:23:36
【问题描述】:

我正在尝试计算空间中任意点生成的面积(橙色)。以下是一些不同可能场景的示例图片:

所以基本上在所有三张图片中,我希望能够通过绘制从点到蓝色区域的水平和垂直线来计算从点生成的橙色区域。这个想法很简单,但实际上实施起来非常具有挑战性。我正在用 R 编写这段代码,所以对 R 代码的任何帮助都会很棒。此外,对于第三个示例,我们可以假设橙色区域的边界为 x 和 y 等于 8。而且,我们还知道绿色点的坐标。任何建议都非常感谢!

哦,这是我生成以下图的代码:

x = c(1,3,5)
y = c(5,3,1)

point1 = c(2,4)
point2 = c(2,2)
point3 = c(0,0)

plot(x,y,type="n",xlim=c(0,8),ylim=c(0,8))
rect(point1[1],point1[2],max(x)+10,max(y)+10,col="orange",border=NA)
rect(x,y,max(x)+10,max(y)+10,col="lightblue",border=NA)
points(x,y,pch=21,bg="green")
points(point1[1],point1[2],pch=21,bg="blue")
box()


plot(x,y,type="n",xlim=c(0,8),ylim=c(0,8))
rect(point2[1],point2[2],max(x)+10,max(y)+10,col="orange",border=NA)
rect(x,y,max(x)+10,max(y)+10,col="lightblue",border=NA)
points(x,y,pch=21,bg="green")
points(point2[1],point2[2],pch=21,bg="blue")
box()


plot(x,y,type="n",xlim=c(0,8),ylim=c(0,8))
rect(point3[1],point3[2],max(x)+10,max(y)+10,col="orange",border=NA)
rect(x,y,max(x)+10,max(y)+10,col="lightblue",border=NA)
points(x,y,pch=21,bg="green")
points(point3[1],point3[2],pch=21,bg="blue")
box()

【问题讨论】:

  • 点是否保证在整数位置?
  • 不,他们不是。我只是这样做是为了便于演示。虽然如果你有一个适用于整数的想法,我会非常有兴趣听到它。
  • 如果点是整数值,您可以存储 1x1 矩形的二维网格。对于每个蓝色矩形,您可以将网格中相应的 1x1 矩形标记为蓝色。然后你可以在最后总结所有非蓝色(又名橙色)的矩形。

标签: r area


【解决方案1】:

你的工作比必要的要努力得多。 pracma::polyarea 将根据所有顶点的坐标计算任何多边形的面积。

【讨论】:

  • 看起来 OP 正在绘制多个重叠的矩形,所以这个函数在这种特殊情况下可能没有帮助。不过,我猜它们形成了一个更复杂的多边形,所以它可能仍然有效。
  • @josilber -- 只要 xe 可以找到橙色区域的所有顶点,在所有显示的示例中,它都是一个不相交的多边形,这意味着它应该可以工作:-)
  • 橙色多边形的许多角没有存储在用于生成绘图的向量xy 中;如何通过算法计算这些角点对我来说并不明显。我们可以手动找到点,当然我们也可以手动找到区域。
  • @josilber 是的,我的情节仅供参考,但我所拥有的只是绿点和蓝点。从视觉上看,这不是一个很难解决的问题,但实际上在算法上实现自动化会让我陷入困境
  • @CarlWitthoft 感谢您的建议,但如果我能找到橙色区域的所有顶点,那么我可以自己计算矩形并将它们相加。
【解决方案2】:

将整个绘图区域想象成一个不等长的矩形网格,x 和 y 网格点位于您要绘制的矩形顶点的 x 和 y 坐标上。

x <- c(1, 3, 5)
y <- c(5, 3, 1)
max.x <- max(x) + 10
max.y <- max(y) + 10
point <- c(0, 0)
x.grid <- sort(unique(c(x, point[1], max.x)))
x.grid
# [1]  0  1  3  5 15
y.grid <- sort(unique(c(y, point[2], max.y)))
y.grid
# [1]  0  1  3  5 15

我们将使用矩阵orange 跟踪我们绘制为橙色的网格矩形:

orange <- matrix(FALSE, nrow=length(y.grid)-1, ncol=length(x.grid)-1)

我们将创建一个绘图函数,根据传递的矩形标记orange 中的单元格,(x1, y1) 位于左下方,(x2, y2) 位于右上方:

plot.rect <- function(x1, y1, x2, y2, value) {
  x1.idx <- which(x.grid == x1)
  y1.idx <- which(y.grid == y1)
  x2.idx <- which(x.grid == x2)
  y2.idx <- which(y.grid == y2)
  orange[y1.idx:(y2.idx-1),x1.idx:(x2.idx-1)] <<- value
}

然后,让我们绘制橙色矩形(填充TRUE),然后绘制所有蓝色矩形(填充FALSE):

plot.rect(point[1], point[2], max.x, max.y, TRUE)
for (idx in 1:length(x)) {
  plot.rect(x[idx], y[idx], max.x, max.y, FALSE)
}

最后,让我们计算每个网格矩形的大小,启用最终大小计算(我在顶部选择的 point 对应于您的第三个图;由于该图向上延伸 15 并向右延伸 15,它似乎按预期工作):

sizes <- t(outer(diff(x.grid), diff(y.grid)))
area <- sum(orange * sizes)
area
# [1] 41

【讨论】:

  • 此代码不起作用。尝试点在 (2,4) 处的第一个图。橙色区域为 1,但您的代码返回 2。
  • 我已经翻转了函数中的索引——它现在应该可以为你工作了。
  • 我在这个程序中仍然得到了一些不好的答案。当蓝点落在蓝色阴影区域(即面积 = 0)时是否有效,如果点具有相同的 x 或 y 坐标(即点彼此重叠)是否有效。
  • 它应该适用于两种情况——你能举一个你认为不正确的结果的例子吗?代码很简单——我建议你通读一遍并理解它在做什么。
  • 实际上我确实通读了,即使它们是简单的命令,这个想法仍然暗示着我。
猜你喜欢
  • 2014-06-15
  • 2021-10-21
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
相关资源
最近更新 更多