tags:

views:

1314

answers:

4

Maths101 question - does anyone know how to calculate an ellipse (width/height) that will enclose a given rectangle. Obviously there is no single ellipse - I'm after an algorithm that will give me various width/height combinations - or perhaps the smallest area of ellipse? It's for a GUI, so an aesthetically pleasing ratio of height/width is what I'm looking for.

Thanks in advance.

+7  A: 

If you give your ellipse the same aspect ratio as the rectangle, you can work on the basis that what you want is a circle enclosing a square then stretched as if you've transformed the square into the required rectangle.

For a square with half side length = 1, the radius of the circle would be sqrt(2).

So, sweeping theta from 0 - 360', the ellipse's coordinate points will be:

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

where rect.width and rect.height are the half widths of the relevant sides.

Alnitak
Very nice solution, +1.
mstrobl
actually it's not quite right yet - I'm still working on it...
Alnitak
ok, I think the maths is actually right now. I've tested the formulae on Grapher.app
Alnitak
This is perfect. To be absolutely clear, you can get the dimensions of the bounding ellipse by just multiplying the dimensions of the rectangle by sqrt(2).
Xanthir
+1  A: 

Assuming you mean circumscribed (which is more precise than "enclosed"), you can read about how to circumscribe a rectangle here. From there, you can stretch it to rectangular, as Alnitak says.

Ian Varley
+2  A: 

The equation for a ellipse centered in the origin is

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

Now if you want to enclose a rectangle of MxN with a eclipse you can move its center to the origin of coordinates. The top right coordinates are (M/2,N/2), replacing in the ellipse equation you have a formula you can use to solve B given A (or A given B).

If you have a rectangle of 4x2, the top-right coordinates are (2,1), replacing you have the (2/A)^2 + (1/B)^2 = 1, then if A=4 solving for B gives B=1/sqrt(1-(1/2)^2).

Ismael
Thanks for the explanation - makes total sense now.
+1  A: 

Experimentally, I found that an ellipse defined by a rectangle that is sqrt(2) larger than the inner rectangle works. So pass sqrt(2) to this function, and you will get the appropriate rectangle:

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

private RectangleF GetScaledRectangle(RectangleF rect, float scale) { float width = rect.Width * scale; float height = rect.Height * scale;

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);

}

Charlie