• 11
• 9
• 12
• 9
• 11

# Draw ellipse within rectangle

This topic is 1149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

Just having an annoying problem that is just on the edge of my sight.  I have a function to draw a circle:

void CircleShape(int size)
{
Vector2 center = new Vector2(size / 2, size / 2);
for (int y = 0; y < size; y++)
{
int dy = (center.y - y);

for (int x = 0; x < size; x++)
{
int dx = (center.x - x);

double dist = Mathf.Sqrt(dx * dx + dy * dy);

if (dist <= (size / 2))
{
SetPixel(x, y, Color.white);
}
}
}
}


I would like to have to be able to provide a width, height instead of just size to be able to produce a circle or ellipse.  Does that completely change my code or is there a simpler solution here?

Thanks,

Scott

##### Share on other sites

I would like to have to be able to provide a width, height instead of just size to be able to produce a circle or ellipse. Does that completely change my code or is there a simpler solution here?

Yes, it will change your code. No, there isn't a simpler solution. You'll also have to decide what you mean by "height" and "width."

That is, the general formula for the locus of points on an ellipse with semi-major and -minor axes aligned with the x/y axes, and centered at the origin is:

x2 / a2 + y2 / b2 = 1

EDIT: Note that describes a circle if a = b = r.

That link also describes the locus for an ellipse not centered at the origin.

Off the top of my head - Given y:  x = sqrt( a2 * ( 1 - y2 / b2 ) )

EDIT2: Note that sqrt has 2 roots, a positive and negative. I.e., for each y value there will be 2 solutions for x, one on either side of the y axis. Further, if you decide to implement your function using that approach, you can range y from 0 to b, and plot points at (-x, -y), (-x, +y), (+x, -y) and (+x, +y). That is more efficient because it gives you 4 points for the price of 1 sqrt.

Depending on your implementation, that's a lot of sqrt's (which are expensive computationally). However, that should give you an idea.

Edited by Buckeye

##### Share on other sites

Thank you!  I came across that formula shortly before heading out for groceries, having you reply with it saves me the trouble of determining if that's what I needed.  Thanks for the quick reply and with 2 edits!

##### Share on other sites

Here is some code I've used in the past. Fully integer based, which may or may not be needed, but it draws an ellipse within a rectangle.

void FrameEllipse(long left,long top,long right,long bottom)
{
long		a,b,x,y,temp;
long long	d1,d2;
long long	a2,b2,a2b2,a2sqr,b2sqr,a4sqr,b4sqr;
long long	a8sqr,b8sqr,a4sqr_b4sqr;
long long	fn,fnw,fw;
long long	fnn,fnnw,fnwn,fnwnw,fnww,fww,fwnw;

if(right < left)
{
temp = left;
left = right;
right = temp;
}
if(bottom < top)
{
temp = top;
top = bottom;
bottom = temp;
}

a = (right - left) / 2;
b = (bottom - top) / 2;

x = 0;
y = b;

a2 = a * a;
b2 = b * b;
a2b2 = a2 + b2;
a2sqr = a2 + a2;
b2sqr = b2 + b2;
a4sqr = a2sqr + a2sqr;
b4sqr = b2sqr + b2sqr;
a8sqr = a4sqr + a4sqr;
b8sqr = b4sqr + b4sqr;
a4sqr_b4sqr = a4sqr + b4sqr;

fn = a8sqr + a4sqr;
fnn = a8sqr;
fnnw = a8sqr;
fnw = a8sqr + a4sqr - b8sqr * a + b8sqr;
fnwn = a8sqr;
fnwnw = a8sqr + b8sqr;
fnww = b8sqr;
fwnw = b8sqr;
fww = b8sqr;
d1 = b2 - b4sqr * a + a4sqr;

while((fnw < a2b2) || (d1 < 0) || ((fnw - fn > b2) && (y > 0)))
{
SetPixel(right - x,bottom - y,Color.white);
SetPixel(left + x,bottom - y,Color.white);
SetPixel(left + x,top + y,Color.white);
SetPixel(right - x,top + y,Color.white);

y--;
if((d1 < 0) || (fnw - fn > b2))
{
d1 += fn;
fn += fnn;
fnw += fnwn;
}else{
x++;
d1 += fnw;
fn += fnnw;
fnw += fnwnw;
}
}

fw = fnw - fn + b4sqr;
d2 = d1 + (fw + fw - fn - fn + a4sqr_b4sqr + a8sqr) / 4;
fnw += b4sqr - a4sqr;

while(x <= a)
{
SetPixel(right - x,bottom - y,Color.white);
SetPixel(left + x,bottom - y,Color.white);
SetPixel(left + x,top + y,Color.white);
SetPixel(right - x,top + y,Color.white);

x++;
if(d2 < 0)
{
y--;
d2 += fnw;
fw += fwnw;
fnw += fnwnw;
}else{
d2 += fw;
fw += fww;
fnw += fnww;
}
}
}