Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

FlyFire

Ellipse equation?

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, you asked for it!

(proc is the equivalent to a putpixel function. this is strictly out of the Allegro graphics library)


/* do_ellipse:
* Helper function for the ellipse drawing routines. Calculates the points
* in an ellipse of radius rx and ry around point x, y, and calls the
* specified routine for each one. The output proc will be passed first a
* copy of the bmp parameter, then the x, y point, then a copy of the d
* parameter (so putpixel() can be used as the callback).
*/
void do_ellipse(BITMAP *bmp, int x, int y, int rx, int ry, int d, void (*proc)())
{
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;

if (rx < 1)
rx = 1;

if (ry < 1)
ry = 1;

h = i = j = k = 0xFFFF;

if (rx > ry) {
ix = 0;
iy = rx * 64;

do {
oh = h;
oi = i;
oj = j;
ok = k;

h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;

if (((h != oh) | | (k != ok)) && (h < oi)) {
proc(bmp, x+h, y+k, d);
if (h)
proc(bmp, x-h, y+k, d);
if (k) {
proc(bmp, x+h, y-k, d);
if (h)
proc(bmp, x-h, y-k, d);
}
}

if (((i != oi) | | (j != oj)) && (h < i)) {
proc(bmp, x+i, y+j, d);
if (i)
proc(bmp, x-i, y+j, d);
if (j) {
proc(bmp, x+i, y-j, d);
if (i)
proc(bmp, x-i, y-j, d);
}
}

ix = ix + iy / rx;
iy = iy - ix / rx;

} while (i > h);
}
else {
ix = 0;
iy = ry * 64;

do {
oh = h;
oi = i;
oj = j;
ok = k;

h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;

if (((j != oj) | | (i != oi)) && (h < i)) {
proc(bmp, x+j, y+i, d);
if (j)
proc(bmp, x-j, y+i, d);
if (i) {
proc(bmp, x+j, y-i, d);
if (j)
proc(bmp, x-j, y-i, d);
}
}

if (((k != ok) | | (h != oh)) && (h < oi)) {
proc(bmp, x+k, y+h, d);
if (k)
proc(bmp, x-k, y+h, d);
if (h) {
proc(bmp, x+k, y-h, d);
if (k)
proc(bmp, x-k, y-h, d);
}
}

ix = ix + iy / ry;
iy = iy - ix / ry;

} while(i > h);
}
}

/* ellipse:
* Draws an ellipse.
*/
void ellipse(BITMAP *bmp, int x, int y, int rx, int ry, int color)
{
int clip, sx, sy, dx, dy;

if (bmp->clip) {
sx = x-rx-1;
sy = y-ry-1;
dx = x+rx+1;
dy = y+ry+1;

if ((sx >= bmp->cr) | | (sy >= bmp->cb) | | (dx < bmp->cl) | | (dy < bmp->ct))
return;

if ((sx >= bmp->cl) && (sy >= bmp->ct) && (dx < bmp->cr) && (dy < bmp->cb))
bmp->clip = FALSE;

clip = TRUE;
}
else
clip = FALSE;

do_ellipse(bmp, x, y, rx, ry, color, bmp->vtable->putpixel);

bmp->clip = clip;
}

Share this post


Link to post
Share on other sites
Advertisement
Okay the general equation of an ellipse for any point is (maths version)

x(theta) = rx cos(theta)
y(theta) = ry sin(theta)
where 0 < theta < 2 pi
rx being the radius in the x, ry being the radius in the y.
So simply take the angle of your point, place it into the equation and find out if it is further from the origin than the point passed back by the equation.

This info was stolen from http://www.swin.edu.au/astronomy/pbourke/
check under geometry for nice 4D shapes and superellipsoid geometry

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
There are some simpler ways to define it. Given radii along each axis -- rx, ry, rz...

The algebraic definition is...


x^2 y^2 z^2
----- + ----- + ----- = 1
rx^2 ry^2 rz^2

The parametric definition requires 2 spherical angles and goes something like this...


X = rx*cos(Phi)*Sin(Theta)
Y = ry*sin(Phi)
Z = rz*cos(Phi)*cos(Theta)

This does depend, though, on how your spherical angles are defined... You can define spherical angles based on which axis you rotate first, and all that. But the basic idea is the normal relationship between an X,Y,Z point and a rho, Phi, Theta point are multiplied by the corresponding axis radii.

- C.P.I. / ASMiNC

Share this post


Link to post
Share on other sites
If gamma is the rotation about the origin then the new point would be
x = rx sin(theta)cos(gamma) + ry cos(theta)sin(gamma)
y = ry cos(theta)cos(gamma) + rx sin(theta)sin(gamma)

where 0 < theta < 2 pi

I used to have the sin(theta) and cos(theta) the other way around, but this way it normally produces a horizontal ellipse when rx is bigger than ry and gamma = 0
(I just did this off the top of my own head from the trigonometry I could remember, so if it's wrong....)

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!