如何从外部逼近一个椭圆?

huangapple go评论81阅读模式
英文:

How to approximate an ellipse from the exterior?

问题

为了解决这个问题关于两个椭圆的重叠,我们从它们的内部近似椭圆。事实上,椭圆是凸的,我们通过连接周围连续的点构建了一条路径。这会产生一个包含在椭圆内部的多边形。

因此,我们最终找到的面积必然小于真实面积:我们得到了面积的下界。

如何构建一个包含椭圆(当然还要近似它),以得到一个上界?似乎不容易通过取切线的小片段来构建一个包络。

英文:

In order to solve this problem about the overlap of two ellipses, we approximate the ellipses from their interior. Indeed an ellipse is convex and we construct a path by joining successive points on the perimeter. This gives a polygon contained in the ellipse.

So the area we find at the end is necessarily less than the true area: we get a lower bound of the area.

How to construct a polygon containing the ellipse (and approximating it of course), in order to get an upper bound? It does not seem easy to construct an envelope by taking small pieces of tangents.

答案1

得分: 2

构建切线并不太难,使用这个答案中提供的椭圆公式。它以参数形式给出椭圆;要获取切线的斜率,请使用(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,其中xy来自于椭圆上的点。

最后,你可以相继交叉这些切线对来获取外多边形的顶点。以下是完整的解决方案:

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

英文:

Constructing the tangents isn't too hard, using the ellipse formula given in this answer. It gives the ellipse in parametric form; to get the slopes of the tangents, use (dy/dtheta)/(dx/dtheta), i.e.

slopes &lt;- (-a * sin(theta) * sin(angle) + b * cos(theta) * cos(angle))/
            (-a * sin(theta) * cos(angle) - b * cos(theta) * sin(angle))

Then the intercepts come from intercepts &lt;- y - slopes*x, where x and y are from points on the ellipse.

Finally, you would intersect successive pairs of those tangent lines to get the vertices of the outer polygon. Here's a complete solution:

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

both &lt;- innerouter(0,0,5, 10, 45, n=10)
plot(both$outer, col = &quot;green&quot;, type = &quot;l&quot;)
lines(both$inner, col = &quot;red&quot;)

如何从外部逼近一个椭圆?<!-- -->

<sup>Created on 2023-05-10 with reprex v2.0.2</sup>

答案2

得分: 0

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

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

如果你能在内多边形的每个点上投出真正的曲面切线,那么你就得到了一个完美的答案(在多边形分辨率上)。如果你简单地使用两个相邻点之间的梯度,那么你可能会生成仍然夹住原始形状的边,但只是刚好。

对于原始问题的一个想法是:你能否将椭圆之一变换,使得另一个椭圆变为圆?在任何维度上挤压椭圆只会创建一个新椭圆。这样做是否能让问题更容易解决?

值得思考一下创建椭圆的其他方式。一个有趣的方法是逆时针旋转的圆。一个圆半径最大值最小值逆时针旋转,同时以相同的角速度顺时针旋转,以半径(最大+最小)/2为中心。初始起始角度定义椭圆的斜率。

也许这两个椭圆的相交点可以表示为扫过角,允许开始和停止积累面积计算的起始点和终止点。不知道。

英文:

Given a set of points that you know is a convex shape, and all the points are on the outline, then that inner polygon has lower area, as you say.

One way to generate a polygon that is larger, is to ensure that each edge of the new outer polygon touches the old polygon at those inner polygon points, ideally it should be tangential at each such point. The points of the new outer polygon would be the intersections of these tangents and lie between the points of the inner polygon.

If you can throw real surface tangents at each of the inner polygon's points then you get a perfect answer (at the polygon resolution). If you simply use the gradient between the 2 neighbour points, then you might generate edges that actually still clip the original shape, but only just.

One thought for the original problem: Could you transform one of the ellipses such that the other ellipse becomes a circle? Squashing an ellipse in any dimension simply creates a new ellipse. Does that make the problem easier to solve?

It is also worth thinking about some of the other ways of creating ellipses. An interesting one is contra-rotating circles. One circle radius max-min spins anticlockwise while orbiting clockwise at the same angular velocity centred at radius (max+min)/2. The initial starting angle defines the slope of the ellipse.

It may be that the interception points of these two ellipses can be represented as the sweep angle, allowing start and stop points for accumulating the area calculation. Dunno.

huangapple
  • 本文由 发表于 2023年5月11日 03:29:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定