R - 计算两个椭圆之间的重叠

J. *_*Doe 3 r graph

首先,是的,之前也有人问过类似的问题。然而,它们都源于PCA或一些专门的包;从这些人在问题中提供的数据中可以看出,这些数据与我拥有的情况不符,我无法使用它。

我有一个数据集,其中包含质心、长轴和短轴以及椭圆的角度。这是一个非常小的例子:

data <- data.frame(x0 = c(0, 0), y0 = c(0, 0), a = c(5, 3), b = c(10, 20), angle = c(45, 35), Ellipse = c("Ell1", "Ell2"))
Run Code Online (Sandbox Code Playgroud)

数据框:

  x0 y0 a  b angle Ellipse
1  0  0 5 10    45    Ell1
2  0  0 3 20    35    Ell2
Run Code Online (Sandbox Code Playgroud)

我还以视觉方式显示它,只是为了教学目的(我不需要绘制重叠区域):

library(ggplot2)
library(ggforce)

ggplot(data, aes(x0 = x0, 
                 y0 = y0,
                 a = a, 
                 b = b, 
                 angle = angle, 
                 color = Ellipse)) + 
  geom_ellipse()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

鉴于此设置,我如何计算重叠面积?

All*_*ron 8

精确解决方案的数学计算在这里非常困难。我认为在 R 中执行此操作的最简单方法是将椭圆创建为多边形并使用sf库来获取它们的交集。然后很容易得到它的面积。

最困难的部分是根据给定的参数创建椭圆,但以下函数应该可以解决问题:

make_ellipse <- function(x0, y0, a, b, angle) {
  angle <- angle/360 * 2 * pi
  theta <- c(seq(0, 2 * pi, length.out = 360), 0)

  crds <- cbind(a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle) + x0,
                a * cos(theta) * sin(angle) + b * sin(theta) * cos(angle) + y0)
  sf::st_polygon(list(crds))
}
Run Code Online (Sandbox Code Playgroud)

这允许我们使用您的数据框来获取省略号,如下所示:

a <- do.call(make_ellipse, data[1, 1:5])
b <- do.call(make_ellipse, data[2, 1:5])
Run Code Online (Sandbox Code Playgroud)

我们可以通过执行以下操作来看到这些是正确的:

plot(b)
plot(a, add = TRUE)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我们可以得到交集如下:

intersection <- sf::st_intersection(a, b)
Run Code Online (Sandbox Code Playgroud)

同样,通过将其添加到我们的图中,我们可以看到这是正确的:

plot(intersection, add = TRUE, col = 'red')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

由于我们确信红色交叉点确实是我们感兴趣的区域的形状,因此我们可以简单地执行以下操作:

sf::st_area(intersection)
#> [1] 105.3689
Run Code Online (Sandbox Code Playgroud)