The draw ellipse command is of course written in C. But I first implemented it in naalaa (which is way easier than rebuilding the runtime for every change). Here's the code I was experimenting with, for the fun of it.
The filled version caused some problems. If any pixel was drawn more than once, it wouldn't work with transparency (some areas of the ellipse would be less transparent than others), so I had to draw horizontal and vertical spans depending on the quadrant.
The code is based on this paper: https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf
The filled version caused some problems. If any pixel was drawn more than once, it wouldn't work with transparency (some areas of the ellipse would be less transparent than others), so I had to draw horizontal and vertical spans depending on the quadrant.
Code:
set redraw off
do
set color 0, 0, 0, 2
cls
set color rnd(256), rnd(256), rnd(256), rnd(256)
x = rnd(640); y = rnd(480)
xr = 32 + rnd(64); yr = 32 + rnd(64)
_FillEllipse x, y, xr, yr
set color rnd(256), rnd(256), rnd(256), rnd(256)
x = rnd(640); y = rnd(480)
xr = 32 + rnd(64); yr = 32 + rnd(64)
_DrawEllipse x, y, xr, yr
redraw
wait 16
until keydown(27, true)
procedure DrawEllipse(cx, cy, xr, yr)
twoasqr = 2*xr*xr
twobsqr = 2*yr*yr
x = xr
y
xc = yr*yr*(1 - 2*xr)
yc = xr*xr
err
sx = twobsqr*xr
sy
while sx >= sy
_PlotEllipse cx, cy, x, y
ADD y 1
ADD sy twoasqr
ADD err yc
ADD yc twoasqr
if 2*err + xc > 0
SUB x 1
SUB sx twobsqr
ADD err xc
ADD xc twobsqr
endif
wend
x
y = yr
xc = yr*yr
yc = xr*xr*(1 - 2*yr)
err
sx
sy = twoasqr*yr
while sx <= sy
_PlotEllipse cx, cy, x, y
ADD x 1
ADD sx twobsqr
ADD err xc
ADD xc twobsqr
if 2*err + yc > 0
SUB y 1
SUB sy twoasqr
ADD err yc
ADD yc twoasqr
endif
wend
endproc
procedure PlotEllipse(cx, cy, x, y)
draw pixel cx + x, cy + y
draw pixel cx - x, cy + y
draw pixel cx - x, cy - y
draw pixel cx + x, cy - y
endproc
procedure FillEllipse(cx, cy, xr, yr)
twoasqr = 2*xr*xr
twobsqr = 2*yr*yr
x = xr
y
xc = yr*yr*(1 - 2*xr)
yc = xr*xr
err
sx = twobsqr*xr
sy
while sx >= sy
_FillEllipseH cx, cy, x, y
ADD y 1
ADD sy twoasqr
ADD err yc
yc = yc + twoasqr
if 2*err + xc > 0
SUB x 1
SUB sx twobsqr
ADD err xc
ADD xc twobsqr
endif
wend
h = y - 1
x
y = yr
xc = yr*yr
yc = xr*xr*(1 - 2*yr)
err
sx
sy = twoasqr*yr
while sx <= sy
_FillEllipseV cx, cy, x, y, h
ADD x 1
ADD sx twobsqr
ADD err xc
ADD xc twobsqr
if 2*err + yc > 0
SUB y 1
SUB sy twoasqr
ADD err yc
ADD yc twoasqr
endif
wend
endproc
procedure FillEllipseH(cx, cy, x, y)
draw rect cx - x, cy - y, x*2 + 1, 1, true
if y <> 0 then draw rect cx - x, cy + y, x*2 + 1, 1, true
endproc
procedure FillEllipseV(cx, cy, x, y, h)
draw rect cx - x, cy - y, 1, y - h, true
draw rect cx - x, cy + h + 1, 1, y - h, true
if x <> 0
draw rect cx + x, cy - y, 1, y - h, true
draw rect cx + x, cy + h + 1, 1, y - h, true
endif
endproc
The code is based on this paper: https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf