【问题标题】:Ellipse bounding a rectangle [closed]包围矩形的椭圆[关闭]
【发布时间】:2009-01-11 18:29:32
【问题描述】:

Maths101 问题 - 有谁知道如何计算包含给定矩形的椭圆(宽度/高度)。显然没有单一的椭圆——我正在寻找一种可以给我各种宽度/高度组合的算法——或者可能是椭圆的最小区域?这是一个 GUI,所以我正在寻找一个美观的高度/宽度比率。

提前致谢。

【问题讨论】:

  • 蜥蜴比尔。数学和编程之间的界限充其量是模糊的,在这种情况下,这与编程完全相关。我需要绘制一个矩形内的渐变。最好的方法是确定椭圆上包围我的矩形的点。巴姆。数学,糟透了。
  • 与编程无关。回答这个问题的关键是从矩形定义的坐标中获取椭圆定义的坐标。答案是数学公式,而不是算法。
  • 如果和编程无关,为什么突然想知道这个问题的答案的时候,我在编程,为什么我在编程的时候只想知道这种问题的答案,或者在数学课上,为什么在谷歌上搜索这个数学答案会导致我最相关地访问这个编程站点?在我看来,标记这个离题的决定是应用了一个过于字面的定义。

标签: math


【解决方案1】:

如果您为椭圆设置与矩形相同的纵横比,您可以根据您想要的是一个包围一个正方形的圆然后拉伸,就好像您已将正方形转换为所需的矩形一样。

对于半边长 = 1 的正方形,圆的半径为 sqrt(2)。

因此,从 0 到 360' 扫描 theta,椭圆的坐标点将是:

  • x = cos(theta) * sqrt(2) * rect.width + x.center;
  • y = sin(theta) * sqrt(2) * rect.height + y.center;

其中rect.width和rect.height是相关边的宽度。

【讨论】:

  • 其实还不太对劲——我还在努力……
  • 好的,我认为数学实际上是正确的。我已经在 Grapher.app 上测试了公式
  • 这是完美的。绝对清楚,您可以通过将矩形的尺寸乘以 sqrt(2) 来获得边界椭圆的尺寸。
  • 如果你想改变纵横比,你可以使用 width' = sqrt(rect.width^2 + ratio^2 * rect.height^2) and height' = width' / ratio with ratio是椭圆的请求纵横比(宽度/高度)。
  • 我最近遇到了同样的(编程)问题,并在将问题发布到数学后发现了这个答案。如果有人仍然感兴趣,我认为我们在那里有一个更通用的解决方案,math.stackexchange.com/questions/2149677/… 并且请参阅上面 JeanMarie 的回答以获取完整的讨论。请注意,您的“sqrt(2) 答案”对应于我们的 n=1 案例。
【解决方案2】:
  1. 椭圆公式为 (x/A)^2+(y/B)^2=1,其中 A 和 B 是椭圆的半径
  2. 矩形边是 Rw 和 Rh
  3. 假设我们想要与矩形具有相同比例的椭圆;那么,如果我们把正方形画成圆形(A=B,Rq=Rh)并挤压它,我们可以很好地保持椭圆 A/B 的比率与矩形边的比率 Rw/Rh 相同;

这导致我们遵循以下方程组:
(x/A)^2+(y/B)^2=1
A/B=Rw/Rh

让我们解决它: A=B*(Rw/Rh)
(Rh/2B)^2+(Rh/2B)^2=1
Rh=sqrt(2)*B

最终解决方案:
A=Rw/sqrt(2)
B=Rh/sqrt(2)

示例:

【讨论】:

    【解决方案3】:

    以原点为中心的椭圆的方程是

    (x/A)^2 + (y/B)^2 = 1
    

    现在,如果您想用日食包围一个 MxN 矩形,您可以将其中心移动到坐标原点。右上角的坐标是(M/2,N/2),在椭圆方程中替换你有一个公式可以用来求解给定A的B(或给定B的A)。

    如果你有一个 4x2 的矩形,右上角的坐标是 (2,1),替换你有 (2/A)^2 + (1/B)^2 = 1,然后如果 A=4 求解 B 得到 B=1/sqrt(1-(1/2)^2)

    【讨论】:

    • 感谢您的解释 - 现在完全有道理了。
    【解决方案4】:

    在实验中,我发现由比内部矩形大 sqrt(2) 的矩形定义的椭圆是有效的。所以将 sqrt(2) 传递给这个函数,你就会得到合适的矩形:

    RectangleF boundingEllipse = GetScaledRectangle(innerRect, Convert.ToSingle(Math.Sqrt(2d)));

    private RectangleF GetScaledRectangle(RectangleF rect, float scale) { 浮动宽度 = rect.Width * 比例; 浮动高度 = rect.Height * 比例;

    float gap = width - rect.Width;
    float left = rect.Left - (gap / 2f);
    
    gap = height - rect.Height;
    float top = rect.Top - (gap / 2f);
    
    return new RectangleF(left, top, width, height);
    

    }

    【讨论】:

      【解决方案5】:

      假设您的意思是受限的(比“封闭”更精确),您可以阅读有关how to circumscribe a rectangle here 的信息。正如 Alnitak 所说,您可以从那里将其拉伸为矩形。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-19
        • 1970-01-01
        • 2015-03-08
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多