# Superellipse

(Redirected from Lame curve)
Superellipse
You are encouraged to solve this task according to the task description, using any language you may know.

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

${\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

## Action!

INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit

PROC Superellipse(INT x0 BYTE y0 REAL POINTER n BYTE a)
INT ARRAY f(100)
REAL ar,xr,tmp1,tmp2,tmp3,one,invn
INT x

IntToReal(1,one)
RealDiv(one,n,invn) ;1/n
IntToReal(a,ar)
Power(ar,n,tmp1) ;a^n

Plot(x0,y0-a)
FOR x=0 TO a
DO
IntToReal(x,xr)
Power(xr,n,tmp2) ;x^n
RealSub(tmp1,tmp2,tmp3) ;a^n-x^n
Power(tmp3,invn,tmp2) ;(a^n-x^n)^(1/n)
f(x)=RealToInt(tmp2)
DrawTo(x0+x,y0-f(x))
OD

x=a
WHILE x>=0
DO
DrawTo(x0+x,y0+f(x))
x==-1
OD

FOR x=0 TO a
DO
DrawTo(x0-x,y0+f(x))
OD

x=a
WHILE x>=0
DO
DrawTo(x0-x,y0-f(x))
x==-1
OD
RETURN

PROC Main()
BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6 REAL n Graphics(8+16) Color=1 COLOR1=$0C
COLOR2=$02 ValR("2.5",n) Superellipse(160,96,n,80) DO UNTIL CH#$FF OD
CH=$FF RETURN Output: ## Ada Library: SDLAda Brute force calculation. with Ada.Numerics.Elementary_Functions; with SDL.Video.Windows.Makers; with SDL.Video.Renderers.Makers; with SDL.Events.Events; procedure Superelipse is Width : constant := 600; Height : constant := 600; A : constant := 200.0; B : constant := 200.0; N : constant := 2.5; Window : SDL.Video.Windows.Window; Renderer : SDL.Video.Renderers.Renderer; Event : SDL.Events.Events.Events; procedure Draw_Superelipse is use type SDL.C.int; use Ada.Numerics.Elementary_Functions; Xx, Yy : Float; subtype Legal_Range is Float range 0.980 .. 1.020; begin for Y in 0 .. Height loop for X in 0 .. Width loop Xx := Float (X - Width / 2); Yy := Float (Y - Height / 2); if (abs (Xx / A)) ** N + (abs (Yy / B)) ** N in Legal_Range then Renderer.Draw (Point => (X => Width / 2 + SDL.C.int (Xx), Y => Height / 2 - SDL.C.int (Yy))); end if; end loop; end loop; end Draw_Superelipse; procedure Wait is use type SDL.Events.Event_Types; begin loop while SDL.Events.Events.Poll (Event) loop if Event.Common.Event_Type = SDL.Events.Quit then return; end if; end loop; delay 0.100; end loop; end Wait; begin if not SDL.Initialise (Flags => SDL.Enable_Screen) then return; end if; SDL.Video.Windows.Makers.Create (Win => Window, Title => "Superelipse", Position => SDL.Natural_Coordinates'(X => 10, Y => 10), Size => SDL.Positive_Sizes'(Width, Height), Flags => 0); SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface); Renderer.Set_Draw_Colour ((0, 0, 0, 255)); Renderer.Fill (Rectangle => (0, 0, Width, Height)); Renderer.Set_Draw_Colour ((0, 220, 0, 255)); Draw_Superelipse; Window.Update_Surface; Wait; Window.Finalize; SDL.Finalise; end Superelipse;  ## AutoHotkey Requires Gdip Library n := 2.5 a := 200 b := 200 SuperEllipse(n, a, b) return SuperEllipse(n, a, b){ global pToken := Gdip_Startup() π := 3.141592653589793, oCoord := [], oX := [], oY := [] nn := 2/n loop 361 { t := (A_Index-1) * π/180 ; https://en.wikipedia.org/wiki/Superellipse x := abs(cos(t))**nn * a * sgn(cos(t)) y := abs(sin(t))**nn * b * sgn(sin(t)) oCoord[A_Index] := [x, y] oX[Floor(x)] := true, oY[Floor(y)] := true } dx := 0 - oX.MinIndex() + 10 dy := 0 - oY.MinIndex() + 10 w := oX.MaxIndex()-oX.MinIndex() + 20 h := oY.MaxIndex()-oY.MinIndex() + 20 Gdip1(w, h) pPen := Gdip_CreatePen("0xFF00FF00", 2) for i, obj in oCoord { x2 := obj.1+dx, y2 := obj.2+dy if i>1 Gdip_DrawLine(G, pPen, x1, y1, x2, y2) x1 := x2, y1 := y2 } UpdateLayeredWindow(hwnd, hdc) } ;---------------------------------------------------------------- sgn(n){ return (n>0?1:n<0?-1:0) } ;---------------------------------------------------------------- Gdip1(w:=0, h:=0){ global w := w ? w : A_ScreenWidth h := h ? h : A_ScreenHeight x := A_ScreenWidth/2 - w/2 y := A_ScreenHeight/2 - h/2 Gui, gdip1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop Gui, gdip1: Show, w%w% h%h% x%x% y%y% hwnd := WinExist() hbm := CreateDIBSection(w, h) hdc := CreateCompatibleDC() obm := SelectObject(hdc, hbm) G := Gdip_GraphicsFromHDC(hdc) Gdip_SetSmoothingMode(G, 4) pBrush := Gdip_BrushCreateSolid("0xFF000000") Gdip_FillRoundedRectangle(G, pBrush, 0, 0, w, h, 5) Gdip_DeleteBrush(pBrush) UpdateLayeredWindow(hwnd, hdc) OnMessage(0x201, "WM_LBUTTONDOWN") } ;---------------------------------------------------------------- Gdip2(){ global SelectObject(hdc, obm) DeleteObject(hbm) DeleteDC(hdc) Gdip_DeleteGraphics(G) Gdip_Shutdown(pToken) } ;---------------------------------------------------------------- WM_LBUTTONDOWN(){ PostMessage, 0xA1, 2 } ;---------------------------------------------------------------- Exit: gdip2() ExitApp Return ;----------------------------------------------------------------  ## C Interactive program to draw a SuperEllipse. Requires the WinBGIm library. #include<graphics.h> #include<stdio.h> #include<math.h> #define pi M_PI int main(){ double a,b,n,i,incr = 0.0001; printf("Enter major and minor axes of the SuperEllipse : "); scanf("%lf%lf",&a,&b); printf("Enter n : "); scanf("%lf",&n); initwindow(500,500,"Superellipse"); for(i=0;i<2*pi;i+=incr){ putpixel(250 + a*pow(fabs(cos(i)),2/n)*(pi/2<i && i<3*pi/2?-1:1),250 + b*pow(fabs(sin(i)),2/n)*(pi<i && i<2*pi?-1:1),15); } printf("Done. %lf",i); getch(); closegraph(); }  ## Delphi Works with: Delphi version 6.0 procedure DrawSuperElipse(Image: TImage); var Points: array of double; const N = 2.5; const Border = 10; var A: integer; var X: integer; var W2,H2: integer; begin {Make elipse size and position based on window size} W2:=Image.Width div 2; H2:=Image.Height div 2; A:=Min(W2,H2)-Border; {Fill array with points} SetLength(Points,A); for X:=0 to High(Points) do Points[X]:=Power(Power(A, N) - Power(X, N), 1 / N); Image.Canvas.Pen.Color:=clRed; Image.Canvas.Pen.Width:=2; {Starting point} Image.Canvas.MoveTo(W2+High(Points),trunc(H2-Points[High(Points)])); {Draw Upper right} for X:=High(Points) downto 0 do begin Image.Canvas.LineTo(W2+x, trunc(H2-Points[X])) end; {Draw Upper left} for X:=0 to High(Points) do begin Image.Canvas.LineTo(W2-X, trunc(H2-Points[X])) end; {Draw Lower left} for X:=High(Points) downto 0 do begin Image.Canvas.LineTo(W2-X, trunc(H2+Points[X])) end; {Draw Lower right} for X:=0 to High(Points) do begin Image.Canvas.LineTo(W2+X, trunc(H2+Points[X])) end; {Connect back to beginning} Image.Canvas.LineTo(W2+High(Points),trunc(H2-Points[High(Points)])); Image.Repaint; end;  Output: Elapsed Time: 13.282 ms.  ## EasyLang n = 2.5 a = 200 b = 200 linewidth 0.2 while t <= 360 x = pow abs cos t (2 / n) * a * sign cos t y = pow abs sin t (2 / n) * b * sign sin t line x / 5 + 50 y / 5 + 50 t += 0.5 .  ## EchoLisp Link to the super-ellipse image. (lib 'plot) (define (eaxpt x n) (expt (abs x) n)) (define (Ellie x y) (+ (eaxpt (// x 200) 2.5) (eaxpt (// y 200) 2.5) -1)) (plot-xy Ellie -400 -400) → (("x:auto" -400 400) ("y:auto" -400 400))  ## FreeBASIC ' version 23-10-2016 ' compile with: fbc -s console Const scr_x = 800 ' screen 800 x 800 Const scr_y = 600 Const m_x = scr_x \ 2 ' middle of screen Const m_y = scr_y \ 2 Sub superellipse(a As Long, b As Long, n As Double) ReDim As Long y(0 To a) Dim As Long x y(0) = b ' value for x = 0 y(a) = 0 ' value for x = a '(0,0) is in upper left corner PSet (m_x, m_y - y(0)) ' set starting point For x = 1 To a-1 y(x) = Int( Exp( Log(1 - ((x / a) ^ n)) / n ) * b ) Line - ((m_x + x), (m_y - y(x))) Next For x = a To 0 Step -1 Line - ((m_x + x), (m_y + y(x))) Next For x = 0 To a Line - ((m_x - x), (m_y + y(x))) Next For x = a To 0 Step -1 Line - ((m_x - x), (m_y - y(x))) Next End Sub ' ------=< MAIN >=------ ScreenRes scr_x, scr_y, 32 Dim As Long a = 200 Dim As Long b = 150 Dim As Double n = 2.5 superellipse(a, b, n) ' empty keyboard buffer While Inkey <> "" : Wend Print : Print "hit any key to end program" Sleep End  ## Go Library: Go Graphics package main import ( "github.com/fogleman/gg" "math" ) /* assumes a and b are always equal */ func superEllipse(dc *gg.Context, n float64, a int) { hw := float64(dc.Width() / 2) hh := float64(dc.Height() / 2) // calculate y for each x y := make([]float64, a+1) for x := 0; x <= a; x++ { aa := math.Pow(float64(a), n) xx := math.Pow(float64(x), n) y[x] = math.Pow(aa-xx, 1.0/n) } // draw quadrants for x := a; x >= 0; x-- { dc.LineTo(hw+float64(x), hh-y[x]) } for x := 0; x <= a; x++ { dc.LineTo(hw+float64(x), hh+y[x]) } for x := a; x >= 0; x-- { dc.LineTo(hw-float64(x), hh+y[x]) } for x := 0; x <= a; x++ { dc.LineTo(hw-float64(x), hh-y[x]) } dc.SetRGB(1, 1, 1) // white ellipse dc.Fill() } func main() { dc := gg.NewContext(500, 500) dc.SetRGB(0, 0, 0) // black background dc.Clear() superEllipse(dc, 2.5, 200) dc.SavePNG("superellipse.png") }  Output: Image similar to J entry.  ## Haskell Use the ghcjs compiler to compile to JavaScript that runs in a browser. The reflex-dom library is used to help with SVG rendering and input. {-# LANGUAGE OverloadedStrings, RankNTypes #-} import Reflex import Reflex.Dom import Data.Text (Text, pack, unpack) import Data.Map (Map, fromList, empty) import Text.Read (readMaybe) width = 600 height = 500 type Point = (Float,Float) type Segment = (Point,Point) data Ellipse = Ellipse {a :: Float, b :: Float, n :: Float} toFloat :: Text -> Maybe Float toFloat = readMaybe.unpack toEllipse :: Maybe Float -> Maybe Float -> Maybe Float -> Maybe Ellipse toEllipse (Just a) (Just b) (Just n) = if a < 1.0 || b <= 1.0 || n <= 0.0 -- not all floats are valid then Nothing else Just$ Ellipse a b n

toEllipse _ _ _ = Nothing

showError :: Maybe a -> String
showError Nothing = "invalid input"
showError _ = ""

reflect45 pts  =  pts ++ fmap (\(x,y) -> ( y,  x)) (reverse pts)
rotate90  pts  =  pts ++ fmap (\(x,y) -> ( y, -x)) pts
rotate180 pts  =  pts ++ fmap (\(x,y) -> (-x, -y)) pts
scale a b      =  fmap (\(x,y) -> ( a*x, b*y ))
segments  pts  =  zip pts $tail pts toLineMap :: Maybe Ellipse -> Map Int ((Float,Float),(Float,Float)) toLineMap (Just (Ellipse a b n)) = let f p = (1 - p**n)**(1/n) dp = iterate (*0.9) 1.0 ip = map (\p -> 1.0 -p) dp points s = if n > 1.0 then (\p -> zip p (map f p)) ip else (\p -> zip (map f p) p) dp in fromList$  -- changes list to map (for listWithKey)
zip [0..] $-- annotates segments with index segments$  -- changes points to line segments
scale a b $rotate180$ -- doubles the point count
rotate90 $-- doubles the point count reflect45$ -- doubles the point count
takeWhile (\(x,y) -> x < y ) $-- stop at 45 degree line points 0.9 toLineMap Nothing = empty lineAttrs :: Segment -> Map Text Text lineAttrs ((x1,y1), (x2,y2)) = fromList [ ( "x1", pack$ show (width/2+x1))
, ( "y1",    pack $show (height/2+y1)) , ( "x2", pack$ show (width/2+x2))
, ( "y2",    pack $show (height/2+y2)) , ( "style", "stroke:brown;stroke-width:2") ] showLine :: MonadWidget t m => Int -> Dynamic t Segment -> m () showLine _ dSegment = do elSvgns "line" (lineAttrs <$> dSegment) $return () return () main = mainWidget$ do
elAttr "h1" ("style" =: "color:brown") $text "Superellipse" ta <- el "div"$ do
text "a: "
textInput def { _textInputConfig_initialValue = "200"}

tb <- el "div" $do text "b: " textInput def { _textInputConfig_initialValue = "200"} tn <- el "div"$ do
text "n: "
textInput def { _textInputConfig_initialValue = "2.5"}
let
ab = zipDynWith toEllipse (toFloat <$> value ta) (toFloat <$> value tb)
dEllipse = zipDynWith ($) ab (toFloat <$> value tn)
dLines = fmap toLineMap dEllipse

dAttrs = constDyn $fromList [ ("width" , pack$ show width)
, ("height", pack $show height) ] elAttr "div" ("style" =: "color:red")$ dynText $fmap (pack.showError) dEllipse el "div"$ elSvgns "svg" dAttrs $listWithKey dLines showLine return () -- At end to avoid Rosetta Code unmatched quotes problem. elSvgns :: forall t m a. MonadWidget t m => Text -> Dynamic t (Map Text Text) -> m a -> m (El t, a) elSvgns = elDynAttrNS' (Just "http://www.w3.org/2000/svg")  Link to live demo: https://dc25.github.io/superEllipseReflex/ ## J We will fill the ellipse so that we do not have to worry about the size and shape of our pixels: selips=: 4 :0 'n a b'=. y 1 >: ((n^~a%~]) +&|/ n^~b%~]) i:x ) require'viewmat' viewmat 300 selips 2.5 200 200  ## Java Works with: Java version 8 import java.awt.*; import java.awt.geom.Path2D; import static java.lang.Math.pow; import java.util.Hashtable; import javax.swing.*; import javax.swing.event.*; public class SuperEllipse extends JPanel implements ChangeListener { private double exp = 2.5; public SuperEllipse() { setPreferredSize(new Dimension(650, 650)); setBackground(Color.white); setFont(new Font("Serif", Font.PLAIN, 18)); } void drawGrid(Graphics2D g) { g.setStroke(new BasicStroke(2)); g.setColor(new Color(0xEEEEEE)); int w = getWidth(); int h = getHeight(); int spacing = 25; for (int i = 0; i < w / spacing; i++) { g.drawLine(0, i * spacing, w, i * spacing); g.drawLine(i * spacing, 0, i * spacing, w); } g.drawLine(0, h - 1, w, h - 1); g.setColor(new Color(0xAAAAAA)); g.drawLine(0, w / 2, w, w / 2); g.drawLine(w / 2, 0, w / 2, w); } void drawLegend(Graphics2D g) { g.setColor(Color.black); g.setFont(getFont()); g.drawString("n = " + String.valueOf(exp), getWidth() - 150, 45); g.drawString("a = b = 200", getWidth() - 150, 75); } void drawEllipse(Graphics2D g) { final int a = 200; // a = b double[] points = new double[a + 1]; Path2D p = new Path2D.Double(); p.moveTo(a, 0); // calculate first quadrant for (int x = a; x >= 0; x--) { points[x] = pow(pow(a, exp) - pow(x, exp), 1 / exp); // solve for y p.lineTo(x, -points[x]); } // mirror to others for (int x = 0; x <= a; x++) p.lineTo(x, points[x]); for (int x = a; x >= 0; x--) p.lineTo(-x, points[x]); for (int x = 0; x <= a; x++) p.lineTo(-x, -points[x]); g.translate(getWidth() / 2, getHeight() / 2); g.setStroke(new BasicStroke(2)); g.setColor(new Color(0x25B0C4DE, true)); g.fill(p); g.setColor(new Color(0xB0C4DE)); // LightSteelBlue g.draw(p); } @Override public void paintComponent(Graphics gg) { super.paintComponent(gg); Graphics2D g = (Graphics2D) gg; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); drawGrid(g); drawLegend(g); drawEllipse(g); } @Override public void stateChanged(ChangeEvent e) { JSlider source = (JSlider) e.getSource(); exp = source.getValue() / 2.0; repaint(); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("Super Ellipse"); f.setResizable(false); SuperEllipse panel = new SuperEllipse(); f.add(panel, BorderLayout.CENTER); JSlider exponent = new JSlider(JSlider.HORIZONTAL, 1, 9, 5); exponent.addChangeListener(panel); exponent.setMajorTickSpacing(1); exponent.setPaintLabels(true); exponent.setBackground(Color.white); exponent.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); Hashtable<Integer, JLabel> labelTable = new Hashtable<>(); for (int i = 1; i < 10; i++) labelTable.put(i, new JLabel(String.valueOf(i * 0.5))); exponent.setLabelTable(labelTable); f.add(exponent, BorderLayout.SOUTH); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); }); } }  ## JavaScript var n = 2.5, a = 200, b = 200, ctx; function point( x, y ) { ctx.fillRect( x, y, 1, 1); } function start() { var can = document.createElement('canvas'); can.width = can.height = 600; ctx = can.getContext( "2d" ); ctx.rect( 0, 0, can.width, can.height ); ctx.fillStyle = "#000000"; ctx.fill(); document.body.appendChild( can ); ctx.fillStyle = "#ffffff"; for( var t = 0; t < 1000; t += .1 ) { x = Math.pow( Math.abs( Math.cos( t ) ), 2 / n ) * a * Math.sign( Math.cos( t ) ); y = Math.pow( Math.abs( Math.sin( t ) ), 2 / n ) * b * Math.sign( Math.sin( t ) ); point( x + ( can.width >> 1 ), y + ( can.height >> 1 ) ); } }  ## jq Adapted from Sidef Works with: jq Also works with gojq, the Go implementation of jq. This entry uses jq to generate SVG. Generic functions # Input: [x, y] def mult($a; $b): [.[0]*$a, .[1]*$b] ; # Input: a number def round($n): . * $n | floor /$n;

# svg header boilerplate
def svg($h;$w):
"<?xml version='1.0' standalone='no'?>",
"<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>",
"<svg height='\($h)' width='\($w)' version='1.1' xmlns='http://www.w3.org/2000/svg'>";
</syntaxhighlight�>
'''Superellipse functions'''
<syntaxhighlight lang=jq>
# y in terms of x
# input: {a,b,n}
def y($x): (.b * pow( (1 - pow( ($x/.a)|length ; .n) ) ; 1/.n )) | round(10);

# input: {a,b,n}
def pline(q):
"<polyline points='\(q|map(join(","))|join(" "))'",
" style='fill:none; stroke:black; stroke-width:3' transform='translate(\(.a + 10), \(.b + 10))' />";

# input: {a,b,n}
def plot:
# points for one quadrant
[range(0;400) as $i | [$i, y($i)] | select(.[1] | isnan | not) ] as$q
|
pline($q), pline($q | map( mult(1;-1))),  # flip and mirror
pline($q | map( mult(-1;-1))), # for the other pline($q | map( mult(-1;1)))   # three quadrants
;

# Input: {a,b,n} - the constants for the superellipse
def superellipse:
svg(.b*2 + 10; .a*2 + 10), plot, "</svg>";

{ a: 200,  b: 200,  n: 2.5 }
| superellipse
Output:

Similar to Perl solution.

## Julia

function superellipse(n, a, b, step::Int=100)
@assert n > 0 && a > 0 && b > 0
na = 2 / n
pc = 2π / step
t  = 0
xp = Vector{Float64}(undef, step + 1)
yp = Vector{Float64}(undef, step + 1)
for i in 0:step
# because sin^n(x) is mathematically the same as (sin(x))^n...
xp[i+1] = abs((cos(t))) ^ na * a * sign(cos(t))
yp[i+1] = abs((sin(t))) ^ na * b * sign(sin(t))
t += pc
end
return xp, yp
end

using UnicodePlots

x, y = superellipse(2.5, 200, 200)
println(lineplot(x, y))

Output:
        ┌────────────────────────────────────────┐
200 │⠀⠀⠀⠀⠀⠀⠀⢀⣠⠤⠔⠒⠊⠉⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠒⠒⠢⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀│
│⠀⠀⠀⠀⣀⠤⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⠤⣀⠀⠀⠀⠀│
│⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⡄⠀⠀│
│⠀⡠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀│
│⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆│
│⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱│
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼│
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│
│⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸│
│⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇│
│⠀⠱⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀│
│⠀⠀⠘⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡔⠁⠀⠀│
│⠀⠀⠀⠀⠉⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠒⠉⠀⠀⠀⠀│
-200 │⠀⠀⠀⠀⠀⠀⠀⠈⠉⠒⠢⠤⠤⣀⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⡠⠤⠔⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀│
└────────────────────────────────────────┘
-200                                   200



## Kotlin

The following is based on the Java entry but dispenses with the grid and slider as these aren't really part of the task.

// version 1.1.2

import java.awt.*
import java.awt.geom.Path2D
import javax.swing.*
import java.lang.Math.pow

/* assumes a == b */
class SuperEllipse(val n: Double, val a: Int) : JPanel() {
init {
require(n > 0.0 && a > 0)
preferredSize = Dimension(650, 650)
background = Color.black
}

private fun drawEllipse(g: Graphics2D) {
val points = DoubleArray(a + 1)
val p = Path2D.Double()
p.moveTo(a.toDouble(), 0.0)

// calculate first quadrant
for (x in a downTo 0) {
points[x] = pow(pow(a.toDouble(), n) - pow(x.toDouble(), n), 1.0 / n)
p.lineTo(x.toDouble(), -points[x])
}

// mirror to others
for (x in 0..a) p.lineTo(x.toDouble(), points[x])
for (x in a downTo 0) p.lineTo(-x.toDouble(), points[x])
for (x in 0..a) p.lineTo(-x.toDouble(), -points[x])

with(g) {
translate(width / 2, height / 2)
color = Color.yellow
fill(p)
}
}

override fun paintComponent(gg: Graphics) {
super.paintComponent(gg)
val g = gg as Graphics2D
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON)
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON)
drawEllipse(g)
}
}

fun main(args: Array<String>) {
SwingUtilities.invokeLater {
val f = JFrame()
with (f) {
defaultCloseOperation = JFrame.EXIT_ON_CLOSE
title = "Super Ellipse"
isResizable = false
add(SuperEllipse(2.5, 200), BorderLayout.CENTER)
pack()
setLocationRelativeTo(null)
isVisible = true
}
}
}


## Lambdatalk

Drawing four super-ellipses, a circle, a rounded square, a square, an astroid.

{def superellipse
{def sgn {lambda {:n} {if {< :n 0} then - else +}}}

{lambda {:a :n :t}
{let { {:a :a} {:n {/ 2 :n}}
{:cost {cos {* {PI} :t}}}
{:sint {sin {* {PI} :t}}}
} {sgn :cost}{* :a {pow {abs :cost} :n}}
{sgn :sint}{* :a {pow {abs :sint} :n}}
}}}
-> superellipse


We use SVG and the lib_plot library defining the SVG, AXES, stroke functions to draw four superellipses, a circle, a rounded square (as required), a square and an astroid.

{{SVG 600 600}
{g {AXES 600 600}
{polyline
{@ points="{S.map {superellipse 200 2.5} {S.serie -1 1.01 0.01}}"
{stroke #f00 4}}}
{polyline
{@ points="{S.map {superellipse 200 0.5} {S.serie -1 1.01 0.01}}"
{stroke #0f0 4}}}
{polyline
{@ points="{S.map {superellipse 200 1} {S.serie -1 1.01 0.01}}"
{stroke #888 2}}}
{polyline
{@ points="{S.map {superellipse 200 2} {S.serie -1 1.01 0.01}}"
{stroke #888 2}}}
}}


The output can be seen in http://lambdaway.free.fr/lambdawalks/?view=super_ellipse

## Liberty BASIC

Reworked the Julia version to work and added a loop with a spread on n values.

[start]
nomainwin
UpperLeftX=1:UpperLeftY=1
WindowWidth=800:WindowHeight=600
open "Super Ellipse" for graphics_nf_nsb as #1
#1 "trapclose [q];down;fill black;flush;color green;size 1"

n=1.5
a=200
b=200

for n = 0.1 to 5 step .1
na=2/n
t=.01
for i = 0 to 314
xp=a*sign(cos(t))*abs((cos(t)))^na+350
yp=b*sign(sin(t))*abs((sin(t)))^na+275
t=t+.02
#1 "set ";xp;" ";yp
next i
next n

'plot only the super ellipse for the task
n=2.5
na=2/n
t=.01
#1 "color white;size 4"
for i = 0 to 314
xp=a*sign(cos(t))*abs((cos(t)))^na+350
yp=b*sign(sin(t))*abs((sin(t)))^na+275
t=t+.02
#1 "set ";xp;" ";yp
next i
wait

[q]
close #1
end

function sign(x)
if x<0 then sign=1
if x>0 then sign=-1
if x=0 then sign=0
end function

## Lua

Scale of a and b were reduced to facilitate an ASCII solution:

local abs,cos,floor,pi,pow,sin = math.abs,math.cos,math.floor,math.pi,math.pow,math.sin
local bitmap = {
init = function(self, w, h, value)
self.w, self.h, self.pixels = w, h, {}
for y=1,h do self.pixels[y]={} end
self:clear(value)
end,
clear = function(self, value)
for y=1,self.h do
for x=1,self.w do
self.pixels[y][x] = value or "  "
end
end
end,
set = function(self, x, y, value)
x,y = floor(x+0.5),floor(y+0.5)
if x>0 and y>0 and x<=self.w and y<=self.h then
self.pixels[y][x] = value or "#"
end
end,
superellipse = function(self, ox, oy, n, a, b, c)
local function sgn(n) return n>=0 and 1 or -1 end
for t = 0, 1, 0.002 do
local theta = t * 2 * pi
local x = ox + a * pow(abs(cos(theta)), 2/n) * sgn(cos(theta))
local y = oy + b * pow(abs(sin(theta)), 2/n) * sgn(sin(theta))
self:set(x, y, c)
end
end,
render = function(self)
for y=1,self.h do
print(table.concat(self.pixels[y]))
end
end,
}

bitmap:init(80, 60, "..")
bitmap:superellipse(40, 30, 2.5, 38, 28, "[]")
bitmap:render()

Output:
................................................................................................................................................................
..........................................................[][][][][][][][][][][][][][][][][][][][][]............................................................
............................................[][][][][][][]..........................................[][][][][][][]..............................................
......................................[][][][]..................................................................[][][][]........................................
................................[][][][]..............................................................................[][][][]..................................
............................[][][]..........................................................................................[][][]..............................
........................[][][]..................................................................................................[][][]..........................
......................[][]..........................................................................................................[][]........................
..................[][]..................................................................................................................[][]....................
................[][]......................................................................................................................[][]..................
..............[][]..........................................................................................................................[][]................
............[][]..............................................................................................................................[][]..............
............[]..................................................................................................................................[]..............
..........[]......................................................................................................................................[]............
........[][]......................................................................................................................................[][]..........
........[]..........................................................................................................................................[]..........
......[]..............................................................................................................................................[]........
......[]..............................................................................................................................................[]........
....[][]..............................................................................................................................................[][]......
....[]..................................................................................................................................................[]......
....[]..................................................................................................................................................[]......
....[]..................................................................................................................................................[]......
..[][]..................................................................................................................................................[][]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[]......................................................................................................................................................[]....
..[][]..................................................................................................................................................[][]....
....[]..................................................................................................................................................[]......
....[]..................................................................................................................................................[]......
....[]..................................................................................................................................................[]......
....[][]..............................................................................................................................................[][]......
......[]..............................................................................................................................................[]........
......[]..............................................................................................................................................[]........
........[]..........................................................................................................................................[]..........
........[][]......................................................................................................................................[][]..........
..........[]......................................................................................................................................[]............
............[]..................................................................................................................................[]..............
............[][]..............................................................................................................................[][]..............
..............[][]..........................................................................................................................[][]................
................[][]......................................................................................................................[][]..................
..................[][]..................................................................................................................[][]....................
......................[][]..........................................................................................................[][]........................
........................[][][]..................................................................................................[][][]..........................
............................[][][]..........................................................................................[][][]..............................
................................[][][][]..............................................................................[][][][]..................................
......................................[][][][]..................................................................[][][][]........................................
............................................[][][][][][][]..........................................[][][][][][][]..............................................
..........................................................[][][][][][][][][][][][][][][][][][][][][]............................................................
................................................................................................................................................................
................................................................................................................................................................


## Maple

The built-in command ImplicitPlot accepts an equation in 2 variables:

plots:-implicitplot(abs((1/200)*x^2.5)+abs((1/200)*y^2.5) = 1, x = -10 .. 10, y = -10 .. 10);

## Mathematica /Wolfram Language

The built-in function ContourPlot accepts an equation in 2 variables and creates the desired plot

ContourPlot[Abs[x/200]^2.5 + Abs[y/200]^2.5 == 1, {x, -200, 200}, {y, -200, 200}]


## Nim

Library: imageman
import math
import imageman

const
Size = 600
X0 = Size div 2
Y0 = Size div 2
Background = ColorRGBU [byte 0, 0, 0]
Foreground = ColorRGBU [byte 255, 255, 255]

proc drawSuperEllipse(img: var Image; n: float; a, b: int) =

var yList = newSeq[int](a + 1)
for x in 0..a:
let an = pow(a.toFloat, n)
let bn = pow(b.toFloat, n)
let xn = pow(x.toFloat, n)
let t = max(bn - xn * bn / an, 0.0)   # Avoid negative values due to rounding errors.
yList[x] = pow(t, 1/n).toInt

var pos: seq[Point]
for x in countdown(a, 0):
pos.add (X0 + x, Y0 - yList[x])
for x in 0..a:
pos.add (X0 - x, Y0 - yList[x])
for x in countdown(a, 0):
pos.add (X0 - x, Y0 + yList[x])
for x in 0..a:
pos.add (X0 + x, Y0 + yList[x])
img.drawPolyline(true, Foreground, pos)

var image = initImage[ColorRGBU](Size, Size)
image.fill(Background)
image.drawSuperEllipse(2.5, 200, 200)
image.savePNG("super_ellipse.png", compression = 9)


## ooRexx

This program draws 5 super ellipses:
black 120,120,1.5
blue  160,160,2
red   200,200,2.5
green 240,240,3
black 280,280,4
/* REXX ***************************************************************
* Create a BMP file showing a few super ellipses
**********************************************************************/
Parse Version v
If pos('Regina',v)>0 Then
superegg='superegga.bmp'
Else
superegg='supereggx.bmp'
'erase' superegg
s='424d4600000000000000360000002800000038000000280000000100180000000000'X||,
'1000000000000000000000000000000000000000'x
z.0=0
black='000000'x
white='ffffff'x
red  ='00ff00'x
green='ff0000'x
blue ='0000ff'x
m=80
n=80
hor=m*8      /* 56 */
ver=n*8      /* 40 */
s=overlay(lend(hor),s,19,4)
s=overlay(lend(ver),s,23,4)
z.=copies('f747ff'x,3192%3)
z.=copies('ffffff'x,8*m)
z.0=648
u=320
v=320
Call supegg black,120,120,1.5,u,v
Call supegg blue,160,160,2,u,v
Call supegg red,200,200,2.5,u,v
Call supegg green,240,240,3,u,v
Call supegg black,280,280,4,u,v

Do i=1 To z.0
s=s||z.i
End

Call lineout superegg,s
Call lineout superegg
Exit

supegg:
Parse Arg color,a,b,n,u,v
Do y=0 To b
t=(1-rxCalcpower(y/b,n))
x=a*rxCalcpower(t,1/n)
Call point color,format(u+x,4,0),format(v+y,4,0)
Call point color,format(u-x,4,0),format(v+y,4,0)
Call point color,format(u+x,4,0),format(v-y,4,0)
Call point color,format(u-x,4,0),format(v-y,4,0)
End
Do x=0 To a
t=(1-rxCalcpower(x/b,n))
y=a*rxCalcpower(t,1/n)
Call point color,format(u+x,4,0),format(v+y,4,0)
Call point color,format(u-x,4,0),format(v+y,4,0)
Call point color,format(u+x,4,0),format(v-y,4,0)
Call point color,format(u-x,4,0),format(v-y,4,0)
End
Return

lend:
Return reverse(d2c(arg(1),4))

point: Procedure Expose z.
Call trace 'O'
Parse Arg color,x0,y0
--Say x0 y0
Do x=x0-2 To x0+2
Do y=y0-2 To y0+2
z.y=overlay(copies(color,3),z.y,3*x)
End
End
Return

::requires rxMath library


## Perl

Translation of: Raku
use v5.36;
my($a,$b, $n, @q) = (200, 200, 2.5); # y in terms of x sub y_from_x ($x) { int $b * abs(1 - ($x/$a) **$n ) ** (1/$n) } # find point pairs for one quadrant push @q,$_, y_from_x($_) for 0..$a;

open  $fh, '>', 'superellipse.svg'; print$fh
qq|<svg height="@{[2*$b]}" width="@{[2*$a]}" xmlns="http://www.w3.org/2000/svg">\n|,
pline( 1, 1, @q ),
pline( 1,-1, @q ), # flip and mirror
pline(-1,-1, @q ), # for the other
pline(-1, 1, @q ), # three quadrants
'</svg>';

sub pline ($sx,$sy, @q) {
(@q[2*$_] *=$sx, @q[1+2*$_] *=$sy) for 0 .. $#q/2; qq|<polyline points="@q" style="fill:none;stroke:black;stroke-width:3" transform="translate($a, $b)" />\n| }  Superellipse (offsite image) ## Phix Library: Phix/pGUI Library: Phix/online You can run this online here. -- -- 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()  ## Processing Translation of: C //Aamrun, 29th June 2022 float a = 200, b = 200, n = 2.5; float i, incr = 0.001; int xMul,yMul; size(500,500); stroke(#ff0000); for(i=0;i<2*PI;i+=incr){ if(PI/2<i && i<3*PI/2) xMul = -1; else xMul = 1; if(PI<i && i<2*PI) yMul = -1; else yMul = 1; ellipse(width/2 + xMul * a*pow(abs(cos(i)),2/n),height/2 + yMul * b*pow(abs(sin(i)),2/n),1,1); }  ## Python # Superellipse drawing in Python 2.7.9 # pic can see at http://www.imgup.cz/image/712 import matplotlib.pyplot as plt from math import sin, cos, pi def sgn(x): return ((x>0)-(x<0))*1 a,b,n=200,200,2.5 # param n making shape na=2/n step=100 # accuracy piece=(pi*2)/step xp=[];yp=[] t=0 for t1 in range(step+1): # because sin^n(x) is mathematically the same as (sin(x))^n... x=(abs((cos(t)))**na)*a*sgn(cos(t)) y=(abs((sin(t)))**na)*b*sgn(sin(t)) xp.append(x);yp.append(y) t+=piece plt.plot(xp,yp) # plotting all point from array xp, yp plt.title("Superellipse with parameter "+str(n)) plt.show()  ## QB64 _Title "Super Ellipse" Dim As Integer sw, sh Dim As Single i sw = 480: sh = 480 Screen _NewImage(sw, sh, 8) Cls , 15 'Show different possible Super Ellipse shapes Color 10 For i = 0.2 To 5.0 Step .1 Call SuperEllipse(sw \ 2, sh \ 2, 200, 200, i, 80) Next 'Show task specified Super Ellipse Color 0 Call SuperEllipse(sw \ 2, sh \ 2, 200, 200, 2.5, 200) Sleep System Sub SuperEllipse (cX As Integer, cY As Integer, wide As Integer, high As Integer, pow As Double, segs As Integer) Dim As Double power, inc, theta, cosTheta, sinTheta Dim As Integer x1, y1 'Limit 'pow' to acceptable values If pow < .1 Then pow = .1 If pow > 150 Then pow = 150 power = 2 / pow - 1 inc = 360.0 / segs * 0.0174532925199432957692369 PSet (wide + cX, cY) For theta = inc To 6.28318530717958647692528 + inc Step inc cosTheta = Cos(theta): sinTheta = Sin(theta) x1 = wide * cosTheta * Abs(cosTheta) ^ power + cX y1 = high * sinTheta * Abs(sinTheta) ^ power + cY Line -(x1, y1) Next End Sub ## QBasic SCREEN 12 CLS a = 200 b = 200 n = 2.5 na = 2 / n t = .01 LINE -(520, 245), 0, BF FOR i = 0 TO 314 xp = a * SGN(COS(t)) * ABS((COS(t))) ^ na + 320 yp = b * SGN(SIN(t)) * ABS((SIN(t))) ^ na + 240 t = t + .02 LINE -(xp, yp), 1, BF NEXT i  ## Racket #lang racket (require plot) #;(plot-new-window? #t) (define ((superellipse a b n) x y) (+ (expt (abs (/ x a)) n) (expt (abs (/ y b)) n))) (plot (isoline (superellipse 200 200 2.5) 1 -220 220 -220 220))  ## Raku (formerly Perl 6) my (\a, \b, \n) = 200, 200, 2.5; # y in terms of x sub y ($x) { floor b × (1 - ($x/a).abs ** n ) ** (1/n) } # find point pairs for one quadrant my @q = flat map -> \x { x, y(x) }, ^(a+1); my$out = open('superellipse.svg', :w);
$out.print: [~] qq|<svg height="{b×2}" width="{a×2}" xmlns="http://www.w3.org/2000/svg">\n|, pline( @q ), pline( @q «×» < 1 -1> ), # flip and mirror pline( @q «×» <-1 -1> ), # for the other pline( @q «×» <-1 1> ), # three quadrants '</svg>'; sub pline (@q) { qq|<polyline points="{@q}" style="fill:none;stroke:black;stroke-width:3" transform="translate({a}, {b})" />\n| }  Superellipse (offsite image) ## REXX Translation of: ooRexx Here you can see a picture: http://austria-forum.org/af/User/Pachl%20Walter /* REXX *************************************************************** * Create a BMP file showing a few super ellipses **********************************************************************/ Parse Version v If pos('Regina',v)>0 Then superegg='superegga.bmp' Else superegg='supereggo.bmp' 'erase' superegg s='424d4600000000000000360000002800000038000000280000000100180000000000'X||, '1000000000000000000000000000000000000000'x z.0=0 black='000000'x white='ffffff'x red ='00ff00'x green='ff0000'x blue ='0000ff'x m=80 n=80 hor=m*8 /* 56 */ ver=n*8 /* 40 */ s=overlay(lend(hor),s,19,4) s=overlay(lend(ver),s,23,4) z.=copies('f747ff'x,3192%3) z.=copies('ffffff'x,8*m) z.0=648 u=320 v=320 Call supegg black,080,080,0.5,u,v Call supegg black,110,110,1 ,u,v Call supegg black,140,140,1.5,u,v Call supegg blue ,170,170,2 ,u,v Call supegg red ,200,200,2.5,u,v Call supegg green,230,230,3 ,u,v Call supegg black,260,260,4 ,u,v Call supegg black,290,290,7 ,u,v Do i=1 To z.0 s=s||z.i End Call lineout superegg,s Call lineout superegg Exit supegg: Parse Arg color,a,b,n,u,v Do y=0 To b t=(1-power(y/b,n)) x=a*power(t,1/n) Call point color,format(u+x,4,0),format(v+y,4,0) Call point color,format(u-x,4,0),format(v+y,4,0) Call point color,format(u+x,4,0),format(v-y,4,0) Call point color,format(u-x,4,0),format(v-y,4,0) End Do x=0 To a t=(1-power(x/b,n)) y=a*power(t,1/n) Call point color,format(u+x,4,0),format(v+y,4,0) Call point color,format(u-x,4,0),format(v+y,4,0) Call point color,format(u+x,4,0),format(v-y,4,0) Call point color,format(u-x,4,0),format(v-y,4,0) End Return lend: Return reverse(d2c(arg(1),4)) point: Procedure Expose z. Call trace 'O' Parse Arg color,x0,y0 --Say x0 y0 Do x=x0-2 To x0+2 Do y=y0-2 To y0+2 z.y=overlay(copies(color,3),z.y,3*x) End End Return power: Procedure /*********************************************************************** * Return b**x for any x -- with reasonable or specified precision * 920903 Walter Pachl ***********************************************************************/ Parse Arg b,x,prec If prec<9 Then prec=9 Numeric Digits (2*prec) Numeric Fuzz 3 If b=0 Then Return 0 If b<>'' Then x=x*ln(b,prec+2) o=1 u=1 r=1 Do i=1 By 1 ra=r o=o*x u=u*i r=r+(o/u) If r=ra Then Leave End Numeric Digits (prec) Return r+0 ln: Procedure /*********************************************************************** * Return ln(x) -- with specified precision * Three different series are used for the ranges 0 to 0.5 * 0.5 to 1.5 * 1.5 to infinity * 920903 Walter Pachl ***********************************************************************/ Parse Arg x,prec,b If prec='' Then prec=9 Numeric Digits (2*prec) Numeric Fuzz 3 Select When x<=0 Then r='*** invalid argument ***' When x<0.5 Then Do z=(x-1)/(x+1) o=z r=z k=1 Do i=3 By 2 ra=r k=k+1 o=o*z*z r=r+o/i If r=ra Then Leave End r=2*r End When x<1.5 Then Do z=(x-1) o=z r=z k=1 Do i=2 By 1 ra=r k=k+1 o=-o*z r=r+o/i If r=ra Then Leave End End Otherwise /* 1.5<=x */ Do z=(x+1)/(x-1) o=1/z r=o k=1 Do i=3 By 2 ra=r k=k+1 o=o/(z*z) r=r+o/i If r=ra Then Leave End r=2*r End End If b<>'' Then r=r/ln(b) Numeric Digits (prec) Return r+0  ## Scala ### Java Swing Interoperability import java.awt._ import java.awt.geom.Path2D import java.util import javax.swing._ import javax.swing.event.{ChangeEvent, ChangeListener} object SuperEllipse extends App { SwingUtilities.invokeLater(() => { new JFrame("Super Ellipse") { class SuperEllipse extends JPanel with ChangeListener { setPreferredSize(new Dimension(650, 650)) setBackground(Color.white) setFont(new Font("Serif", Font.PLAIN, 18)) private var exp = 2.5 override def paintComponent(gg: Graphics): Unit = { val g = gg.asInstanceOf[Graphics2D] def drawGrid(g: Graphics2D): Unit = { g.setStroke(new BasicStroke(2)) g.setColor(new Color(0xEEEEEE)) val w = getWidth val h = getHeight val spacing = 25 for (i <- 0 until (w / spacing)) { g.drawLine(0, i * spacing, w, i * spacing) g.drawLine(i * spacing, 0, i * spacing, w) } g.drawLine(0, h - 1, w, h - 1) g.setColor(new Color(0xAAAAAA)) g.drawLine(0, w / 2, w, w / 2) g.drawLine(w / 2, 0, w / 2, w) } def drawLegend(g: Graphics2D): Unit = { g.setColor(Color.black) g.setFont(getFont) g.drawString("n = " + String.valueOf(exp), getWidth - 150, 45) g.drawString("a = b = 200", getWidth - 150, 75) } def drawEllipse(g: Graphics2D): Unit = { val a = 200 // calculate first quadrant val points = Array.tabulate(a + 1)(n => math.pow(math.pow(a, exp) - math.pow(n, exp), 1 / exp)) val p = new Path2D.Double p.moveTo(a, 0) for (n <- a to 0 by -1) p.lineTo(n, -points(n)) // mirror to others for (x <- points.indices) p.lineTo(x, points(x)) for (y <- a to 0 by -1) p.lineTo(-y, points(y)) for (z <- points.indices) p.lineTo(-z, -points(z)) g.translate(getWidth / 2, getHeight / 2) g.setStroke(new BasicStroke(2)) g.setColor(new Color(0x25B0C4DE, true)) g.fill(p) g.setColor(new Color(0xB0C4DE)) // LightSteelBlue g.draw(p) } super.paintComponent(gg) g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON) drawGrid(g) drawLegend(g) drawEllipse(g) } override def stateChanged(e: ChangeEvent): Unit = { val source = e.getSource.asInstanceOf[JSlider] exp = source.getValue / 2.0 repaint() } } setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE) setResizable(false) val panel = new SuperEllipse add(panel, BorderLayout.CENTER) val exponent = new JSlider(SwingConstants.HORIZONTAL, 1, 9, 5) exponent.addChangeListener(panel) exponent.setBackground(Color.white) exponent.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)) exponent.setMajorTickSpacing(1) exponent.setPaintLabels(true) val labelTable = new util.Hashtable[Integer, JLabel] for (i <- 1 until 10) labelTable.put(i, new JLabel(String.valueOf(i * 0.5))) exponent.setLabelTable(labelTable) add(exponent, BorderLayout.SOUTH) pack() setLocationRelativeTo(null) setVisible(true) } }) }  ## Sidef Translation of: Raku const ( a = 200, b = 200, n = 2.5, ) # y in terms of x func y(x) { b * (1 - abs(x/a)**n -> root(n)) -> int } func pline(q) { <<-"EOT"; <polyline points="#{q.join(' ')}" style="fill:none; stroke:black; stroke-width:3" transform="translate(#{a}, #{b})" /> EOT } # Generate an SVG image say <<-"EOT" <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg height="#{b*2}" width="#{a*2}" version="1.1" xmlns="http://www.w3.org/2000/svg"> EOT # find point pairs for one quadrant var q = { |x| (x, y(x)) }.map(0..200 by 2) [ pline(q), pline(q »*« [ 1,-1]), # flip and mirror pline(q »*« [-1,-1]), # for the other pline(q »*« [-1, 1]), # three quadrants ].each { .print } say '</svg>'  ## Stata sca a=200 sca b=200 sca n=2.5 twoway function y=b*(1-(abs(x/a))^n)^(1/n), range(-200 200) || function y=-b*(1-(abs(x/a))^n)^(1/n), range(-200 200)  ## Wren Library: DOME Uses Go's drawing code but produces a more complex image. import "graphics" for Canvas, Color, Point class Game { static init() { Canvas.resize(500, 500) // draw 200 concentric superellipses with gradually decreasing 'n'. for (a in 200..1) { superEllipse(a/80, a) } } static update() {} static draw(alpha) {} static superEllipse(n, a) { var hw = Canvas.width / 2 var hh = Canvas.height / 2 // calculate y for each x var y = List.filled(a + 1, 0) for (x in 0..a) { var aa = a.pow(n) var xx = x.pow(n) y[x] = (aa-xx).pow(1/n) } // draw quadrants var prev = Point.new(hw + a, hh - y[a]) for (x in a-1..0) { var curr = Point.new(hw + x, hh - y[x]) Canvas.line(prev.x, prev.y, curr.x, curr.y, Color.white) prev = Point.new(curr.x, curr.y) } prev = Point.new(hw, hh + y[0]) for (x in 1..a) { var curr = Point.new(hw + x, hh + y[x]) Canvas.line(prev.x, prev.y, curr.x, curr.y, Color.white) prev = Point.new(curr.x, curr.y) } prev = Point.new(hw - a, hh + y[a]) for (x in a-1..0) { var curr = Point.new(hw - x, hh + y[x]) Canvas.line(prev.x, prev.y, curr.x, curr.y, Color.white) prev = Point.new(curr.x, curr.y) } prev = Point.new(hw, hh - y[0]) for (x in 1..a) { var curr = Point.new(hw - x, hh - y[x]) Canvas.line(prev.x, prev.y, curr.x, curr.y, Color.white) prev = Point.new(curr.x, curr.y) } } }  ## XPL0 def X0=640/2, Y0=480/2, Scale=25.0, N=2.5; real X, Y; int IX, IY; proc OctPoint; [ Point(X0+IX, Y0-IY,$F);
Point(X0-IX, Y0-IY, $F); Point(X0+IX, Y0+IY,$F);
Point(X0-IX, Y0+IY, $F); Point(X0+IY, Y0-IX,$F);
Point(X0-IY, Y0-IX, $F); Point(X0+IY, Y0+IX,$F);
Point(X0-IY, Y0+IX, $F); ]; [SetVid($101);  \VESA graphics 640x480x8
IX:= 0;
repeat  X:= float(IX)/Scale;
Y:= Pow(200.0 - Pow(X,N), 1.0/N);
IY:= fix(Y*Scale);
OctPoint;
IX:= IX+1;
until   IX >= IY;
]
Output:
http://www.xpl0.org/rcell.gif


## Yabasic

open window 700, 600
backcolor 0,0,0
clear window

a=200
b=200
n=2.5
na=2/n
t=.01
color 0,0,255
for i = 0 to 314
xp=a*sig(cos(t))*abs((cos(t)))^na+350
yp=b*sig(sin(t))*abs((sin(t)))^na+275
t=t+.02
line to xp, yp
next i

## zkl

Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl

fcn superEllipse(plot,n,color=0xff0000){ // we'll assume width <= height
a,p:=(plot.w/2).toFloat(), 1.0/n;  // just calculate upper right quadrant
foreach x in ([0.0 .. a]){
y:=(a.pow(n) - x.pow(n)).pow(p);  // a==b>0 --> y=(a^n - x^n)^(1/n)
//println( (x/a).abs().pow(n) + (y/b).abs().pow(n) );  // sanity check
plot[x,y]=plot[-x,-y]=plot[-x,y]=plot[x,-y]=color;  // all 4 quadrants
}
plot
}
w:=h:=600;
plot:=PPM(w+1,h+1,0x909090); plot.cross(w/2,h/2);
foreach n in ([0.01..1, 0.14]){ superEllipse(plot,n, 0x0000bb) }// 0-1: blue
foreach n in ([1.0.. 2, 0.14]){ superEllipse(plot,n, 0x00ff00) }// 1-2: green
foreach n in ([2.0..10, 1.4]) { superEllipse(plot,n, 0xff0000) }// 2+:  red

plot.writeJPGFile("superEllipse.jpg");