A superellipse is a geometric figure defined as the set of all points (x, y) with



 





|


x
a


|


n



+


|


y
b


|


n



=
1
,


{\displaystyle \left|{\frac {x}{a}}\right|^{n}\!+\left|{\frac {y}{b}}\right|^{n}\!=1,}




where n, a, and b are positive numbers.



Task
Draw a superellipse with n = 2.5, and a = b = 200




--
-- demo\rosetta\Superellipse.exw
-- =============================
--
with javascript_semantics
atom n = 2.5        -- '+' and '-' increase/decrease in steps of 0.1

include pGUI.e

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

function redraw_cb(Ihandle /*ih*/)

    integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE"),
             hw = floor(w/2), hh = floor(h/2),
             a = max(10,hw-100),    -- (initially 200, from 602x   )
             b = max(10,hh-50)      -- (initially 200, from    x502)
    sequence y = b&repeat(0,a)
    for x=1 to a-1 do
        y[x+1] = floor(exp(log(1-power(x/a,n))/n)*b)
    end for

    cdCanvasActivate(cddbuffer)
    cdCanvasClear(cddbuffer)
    cdCanvasBegin(cddbuffer, CD_OPEN_LINES) 
    cdCanvasVertex(cddbuffer, hw, hh-b) -- starting point
    for x=1 to a-1     do cdCanvasVertex(cddbuffer, hw+x, hh-y[x+1]) end for
    for x=a to 0 by -1 do cdCanvasVertex(cddbuffer, hw+x, hh+y[x+1]) end for
    for x=0 to a       do cdCanvasVertex(cddbuffer, hw-x, hh+y[x+1]) end for
    for x=a to 0 by -1 do cdCanvasVertex(cddbuffer, hw-x, hh-y[x+1]) end for
    cdCanvasEnd(cddbuffer)
    cdCanvasFlush(cddbuffer)

    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    cdcanvas = cdCreateCanvas(CD_IUP, ih)
    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
    cdCanvasSetBackground(cddbuffer, CD_WHITE)
    cdCanvasSetForeground(cddbuffer, CD_BLACK)
    return IUP_DEFAULT
end function

function key_cb(Ihandle /*ih*/, atom c)
    if c=K_ESC then return IUP_CLOSE end if
    if c='+' then
        n = min(130,n+0.1) -- (otherwise [>130] power overflow)
        IupUpdate(canvas)
    elsif c='-' then
        n = max(0.1,n-0.1) -- (otherwise [=0.0] divide by zero)
        IupUpdate(canvas)
    end if
    return IUP_CONTINUE
end function

procedure main()
    IupOpen()
    
    canvas = IupCanvas("RASTERSIZE=602x502")
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "ACTION", Icallback("redraw_cb")})
    dlg = IupDialog(canvas,"TITLE=Superellipse")
    IupSetCallback(dlg, "KEY_CB", Icallback("key_cb"))
    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()
