NaaLaa Forum
Drawing an ellipse - Printable Version

+- NaaLaa Forum (http://www.naalaa.com/community)
+-- Forum: NaaLaa (http://www.naalaa.com/community/forumdisplay.php?fid=1)
+--- Forum: Showcase (http://www.naalaa.com/community/forumdisplay.php?fid=4)
+--- Thread: Drawing an ellipse (/showthread.php?tid=47)



Drawing an ellipse - Marcus - 04-06-2018

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.

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


RE: Drawing an ellipse - johnno56 - 04-06-2018

Very nice. I was expecting maybe a simple ellipse, but a whole screen full of various sizes and transparency - AND filled. Did I mention very fast? Draws SO much quicker using four start points. Very cool. Well done. I have to say, THAT, is a Darth Vader moment!!

J