如何从外表近似椭圆?

问题描述 投票:0回答:2

为了解决这个关于两个椭圆重叠的问题,我们从椭圆的内部逼近椭圆。事实上,椭圆是凸的,我们通过连接周长上的连续点来构建路径。这给出了包含在椭圆中的多边形。

所以我们最后找到的面积必然小于真实面积:我们得到了面积的下界。

如何构造一个包含椭圆的多边形(当然是近似),以获得上限?通过取小段切线来构建信封似乎并不容易。

r math geometry ellipse
2个回答
0
投票

给定一组您知道是凸形的点,并且所有点都在轮廓上,那么正如您所说,内部多边形的面积较小。

生成更大多边形的一种方法是确保新的外部多边形的每条边在那些内部多边形点处接触旧多边形,理想情况下它应该在每个这样的点处相切。新的外部多边形的点将是这些切线的交点,位于内部多边形的点之间。

如果你可以在每个内部多边形的点上抛出真实的表面切线,那么你会得到一个完美的答案(在多边形分辨率下)。如果你简单地使用两个相邻点之间的梯度,那么你可能会生成实际上仍然剪裁原始形状的边缘,但只是。

原题的一个想法:你能不能把其中一个椭圆变换成另一个椭圆变成圆?在任何维度上挤压一个椭圆只会创建一个新的椭圆。这会让问题更容易解决吗?

还值得考虑其他一些创建椭圆的方法。一个有趣的是反向旋转的圆圈。一个圆半径 max-min 以半径 (max+min)/2 为中心,以相同的角速度顺时针旋转,同时逆时针旋转。初始起始角定义椭圆的斜率。

可能这两个椭圆的截点可以表示为掠角,允许起止点累加面积计算。不知道。


0
投票

使用this answer中给出的椭圆公式,构造切线并不难。它以参数形式给出椭圆;要获得切线的斜率,请使用

(dy/dtheta)/(dx/dtheta)
,即

slopes <- (-a * sin(theta) * sin(angle) + b * cos(theta) * cos(angle))/
            (-a * sin(theta) * cos(angle) - b * cos(theta) * sin(angle))

然后截距来自

intercepts <- y - slopes*x
,其中
x
y
是椭圆上的点。

最后,您将相交这些切线的连续对以获得外部多边形的顶点。这是一个完整的解决方案:

innerouter <- function(x0, y0, a, b, angle, n = 360) {
    angle <- angle/360 * 2 * pi
    theta <- c(seq(0, 2 * pi, length.out = n), 0)
    
    slopes <- (-a * sin(theta) * sin(angle) + b * cos(theta) * cos(angle))/
        (-a * sin(theta) * cos(angle) - b * cos(theta) * sin(angle))
    crds <- cbind(a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle) + x0,
                                a * cos(theta) * sin(angle) + b * sin(theta) * cos(angle) + y0)
    intercepts <- crds[,2] - slopes*crds[,1]
    i <- 1:(n-1)
    x <- (intercepts[i] - intercepts[i+1])/(slopes[i+1] - slopes[i])
    y <- slopes[i]*x + intercepts[i]
    outer <- cbind(c(x, x[1]),  c(y, y[1]))
    inner <- crds
    list(inner = inner, outer = outer) 
}

both <- innerouter(0,0,5, 10, 45, n=10)
plot(both$outer, col = "green", type = "l")
lines(both$inner, col = "red")

创建于 2023-05-10 与 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.