I am trying to render ellipse on plotter powered by an MCU so there is low memory to work with and integer arithmetics is preffered.
I've got this equation
and I tried to implement it in C in the following way:
y = sqrt( (b*b) * ( 1 - ( (x*x) / (a*a) )));
where y
, b
, x
and a
are integer values but the results where wrong .
Q1 Is this correct implementation of ellipse equation?
Q2 Are there any other ways to do this?
for plotting the ellipse (outline by lines) is the parametric equation the best.
Here axis aligned ellipse:
x=x0+a*cos(t); y=y0+b*sin(t);
where:
(x0,y0)
is the ellipse center a,b
are the semi-axises t
is angular parameter t=<0,2*M_PI>
t
goes the full circle with some small enough step (x,y)
per each step of t as your x,y,x0,y0,a,b
are integers either convert them to float/double or create integer table for cos[],sin[]
for example:
int tcos[360],tsin[360];
where tcos[i]=float(1000.0*cos(float(i)*M_PI/180.0));
now on use just integers like:
for (i=0;i<360;i++) { x=x0+(a*tcos(i))/1000; y=y0+(b*tsin(i))/1000; //... }
If you need pixel perfect rendering or render filled ellipse
Then you need use different approach (the same as your equation)
for example axis aligned (0,0)
centered ellipse:
for (x=-a;x<=a;x++) { y = sqrt( (b*b) - ( (x*x*b*b) / (a*a) ))); // render pixels: (x,+y) and (x,-y) or join them by line }
if you need integer sqrt
then implement one (instead of using math.h
) for example:
int bits(DWORD p) { DWORD m=0x80000000; int b=32; for (;m;m>>=1,b--) if (p>=m) break; return b; } DWORD sqrt(const DWORD &x) { DWORD m,a; m=(bits(x)>>1); // bits(x) just return position of MSB nonzero bit can use m=16; instead if (m) m=1<<m; else m=1; for (a=0;m;m>>=1) { a|=m; if (a*a>x) a^=m; } return a; }
where DWORD
is unsigned 32 bit int data type.
for filling you do not need the sqrt
You can instead loop through the area and decide if the pixel is inside or not:
for (y=-b;y<=b;y++) for (x=-a;x<=a;x++) if ( (y*y) <= ( (b*b) - ( (x*x*b*b) / (a*a) ) ) ) // render pixel: (x,y)
The implementation is correct. I set y,b,x and a as double values this fixed the wrong output.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.