Superellipse: Difference between revisions
(Added Go) |
|||
(42 intermediate revisions by 21 users not shown) | |||
Line 13: | Line 13: | ||
Draw a superellipse with n = 2.5, and a = b = 200 |
Draw a superellipse with n = 2.5, and a = b = 200 |
||
<br><br> |
<br><br> |
||
=={{header|Action!}}== |
|||
{{libheader|Action! Tool Kit}} |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Superellipse.png Screenshot from Atari 8-bit computer] |
|||
=={{header|Ada}}== |
|||
{{libheader|SDLAda}} Brute force calculation. |
|||
<syntaxhighlight lang="ada">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;</syntaxhighlight> |
|||
=={{header|AutoHotkey}}== |
|||
Requires [https://www.autohotkey.com/boards/viewtopic.php?t=6517 Gdip Library] |
|||
<syntaxhighlight lang="autohotkey">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 |
|||
;----------------------------------------------------------------</syntaxhighlight> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Interactive program to draw a SuperEllipse. Requires the [http://www.cs.colorado.edu/~main/bgi/cs1300/ WinBGIm] library. |
Interactive program to draw a SuperEllipse. Requires the [http://www.cs.colorado.edu/~main/bgi/cs1300/ WinBGIm] library. |
||
<syntaxhighlight lang="c"> |
|||
<lang C> |
|||
#include<graphics.h> |
#include<graphics.h> |
||
#include<stdio.h> |
#include<stdio.h> |
||
Line 43: | Line 266: | ||
closegraph(); |
closegraph(); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
|||
{{works with|Delphi|6.0}} |
|||
{{libheader|SysUtils,StdCtrls}} |
|||
[[File:DelphiSuperElipse.png|frame|none]] |
|||
<syntaxhighlight lang="Delphi"> |
|||
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; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Elapsed Time: 13.282 ms. |
|||
</pre> |
|||
=={{header|EasyLang}}== |
|||
[https://easylang.dev/show/#cod=Vc1LCsMgFEbh+V3FGbYJGLHYUV2MtqERgikomOw+2Bft6L9wPrgJh1FWfFutJbx3jmms8VYmtDJSpziPFC6O01kLsOJ4LBUfMtclUzgYBtKRDk9Hjvf0Ck1vPzrH9KfDRz9D0+03KwOWHqvZvmerhd6hlRUlOw== Run it] |
|||
<syntaxhighlight> |
|||
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 |
|||
. |
|||
</syntaxhighlight> |
|||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
Link to the super-ellipse [http://www.echolalie.org/echolisp/images/super-ellipse.png image]. |
Link to the super-ellipse [http://www.echolalie.org/echolisp/images/super-ellipse.png image]. |
||
< |
<syntaxhighlight lang="scheme"> |
||
(lib 'plot) |
(lib 'plot) |
||
(define (eaxpt x n) (expt (abs x) n)) |
(define (eaxpt x n) (expt (abs x) n)) |
||
Line 54: | Line 354: | ||
(plot-xy Ellie -400 -400) |
(plot-xy Ellie -400 -400) |
||
→ (("x:auto" -400 400) ("y:auto" -400 400)) |
→ (("x:auto" -400 400) ("y:auto" -400 400)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">' version 23-10-2016 |
||
' compile with: fbc -s console |
' compile with: fbc -s console |
||
Line 110: | Line 411: | ||
Print : Print "hit any key to end program" |
Print : Print "hit any key to end program" |
||
Sleep |
Sleep |
||
End</ |
End</syntaxhighlight> |
||
=={{header|Go}}== |
=={{header|Go}}== |
||
{{libheader|Go Graphics}} |
{{libheader|Go Graphics}} |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 158: | Line 459: | ||
superEllipse(dc, 2.5, 200) |
superEllipse(dc, 2.5, 200) |
||
dc.SavePNG("superellipse.png") |
dc.SavePNG("superellipse.png") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 167: | Line 468: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Use the [https://github.com/ghcjs/ghcjs ghcjs compiler ] to compile to JavaScript that runs in a browser. The [https://github.com/reflex-frp/reflex-dom reflex-dom ] library is used to help with SVG rendering and input. |
Use the [https://github.com/ghcjs/ghcjs ghcjs compiler ] to compile to JavaScript that runs in a browser. The [https://github.com/reflex-frp/reflex-dom reflex-dom ] library is used to help with SVG rendering and input. |
||
< |
<syntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings, RankNTypes #-} |
||
import Reflex |
import Reflex |
||
import Reflex.Dom |
import Reflex.Dom |
||
Line 267: | Line 568: | ||
-- At end to avoid Rosetta Code unmatched quotes problem. |
-- 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 :: 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")</ |
elSvgns = elDynAttrNS' (Just "http://www.w3.org/2000/svg")</syntaxhighlight> |
||
Link to live demo: https://dc25.github.io/superEllipseReflex/ |
Link to live demo: https://dc25.github.io/superEllipseReflex/ |
||
Line 276: | Line 577: | ||
We will fill the ellipse so that we do not have to worry about the size and shape of our pixels: |
We will fill the ellipse so that we do not have to worry about the size and shape of our pixels: |
||
< |
<syntaxhighlight lang="j">selips=: 4 :0 |
||
'n a b'=. y |
'n a b'=. y |
||
1 >: ((n^~a%~]) +&|/ n^~b%~]) i:x |
1 >: ((n^~a%~]) +&|/ n^~b%~]) i:x |
||
Line 282: | Line 583: | ||
require'viewmat' |
require'viewmat' |
||
viewmat 300 selips 2.5 200 200</ |
viewmat 300 selips 2.5 200 200</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
[[File:superellipse.png|300px|thumb|right]] |
[[File:superellipse.png|300px|thumb|right]] |
||
{{works with|Java|8}} |
{{works with|Java|8}} |
||
< |
<syntaxhighlight lang="java">import java.awt.*; |
||
import java.awt.geom.Path2D; |
import java.awt.geom.Path2D; |
||
import static java.lang.Math.pow; |
import static java.lang.Math.pow; |
||
Line 412: | Line 713: | ||
}); |
}); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript"> |
||
var n = 2.5, a = 200, b = 200, ctx; |
var n = 2.5, a = 200, b = 200, ctx; |
||
Line 437: | Line 739: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header| |
=={{header|jq}}== |
||
'''Adapted from [[#Sidef|Sidef]]''' |
|||
{{works with|Julia|0.6}} |
|||
{{works with|jq}} |
|||
'''Also works with gojq, the Go implementation of jq'''. |
|||
<lang julia>function superellipse(n, a, b, step::Int=100) |
|||
This entry uses jq to generate SVG. |
|||
'''Generic functions''' |
|||
<syntaxhighlight lang=jq> |
|||
# 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 |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
Similar to [https://github.com/SqrtNegInf/Rosettacode-Perl-Smoke/blob/master/ref/superellipse.svg Perl solution]. |
|||
=={{header|Julia}}== |
|||
<syntaxhighlight lang="julia">function superellipse(n, a, b, step::Int=100) |
|||
@assert n > 0 && a > 0 && b > 0 |
@assert n > 0 && a > 0 && b > 0 |
||
na = 2 / n |
na = 2 / n |
||
pc = 2π / step |
pc = 2π / step |
||
t = 0 |
t = 0 |
||
xp = Vector{Float64}(step + 1) |
xp = Vector{Float64}(undef, step + 1) |
||
yp = Vector{Float64}(step + 1) |
yp = Vector{Float64}(undef, step + 1) |
||
for i in 0:step |
for i in 0:step |
||
# because sin^n(x) is mathematically the same as (sin(x))^n... |
# because sin^n(x) is mathematically the same as (sin(x))^n... |
||
Line 461: | Line 815: | ||
x, y = superellipse(2.5, 200, 200) |
x, y = superellipse(2.5, 200, 200) |
||
println(lineplot(x, y))</ |
println(lineplot(x, y))</syntaxhighlight>{{out}} |
||
{{out}} |
|||
<pre> |
<pre> |
||
┌────────────────────────────────────────┐ |
┌────────────────────────────────────────┐ |
||
200 │⠀⠀⠀⠀⠀⠀⠀⢀⣠⠤⠔⠒⠊⠉⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠒⠒⠢⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀│ |
200 │⠀⠀⠀⠀⠀⠀⠀⢀⣠⠤⠔⠒⠊⠉⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠒⠒⠢⠤⣀⡀⠀⠀⠀⠀⠀⠀⠀│ |
||
│⠀⠀⠀⠀⣀⠤⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⠤⣀⠀⠀⠀⠀│ |
│⠀⠀⠀⠀⣀⠤⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⠤⣀⠀⠀⠀⠀│ |
||
│⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⡄⠀⠀│ |
│⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⡄⠀⠀│ |
||
│⠀⡠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀│ |
│⠀⡠⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢆⠀│ |
||
│⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆│ |
│⢰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡆│ |
||
│⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱│ |
│⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢱│ |
||
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│ |
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│ |
||
│⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼│ |
│⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼│ |
||
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│ |
│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸│ |
||
│⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸│ |
│⢇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸│ |
||
│⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇│ |
│⠸⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇│ |
||
│⠀⠱⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀│ |
│⠀⠱⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀│ |
||
│⠀⠀⠘⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡔⠁⠀⠀│ |
│⠀⠀⠘⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡔⠁⠀⠀│ |
||
│⠀⠀⠀⠀⠉⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠒⠉⠀⠀⠀⠀│ |
│⠀⠀⠀⠀⠉⠒⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠒⠉⠀⠀⠀⠀│ |
||
-200 │⠀⠀⠀⠀⠀⠀⠀⠈⠉⠒⠢⠤⠤⣀⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⡠⠤⠔⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀│ |
-200 │⠀⠀⠀⠀⠀⠀⠀⠈⠉⠒⠢⠤⠤⣀⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⡠⠤⠔⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀│ |
||
└────────────────────────────────────────┘ |
└────────────────────────────────────────┘ |
||
-200 200 |
-200 200 |
||
</pre> |
|||
=={{header|Kotlin}}== |
=={{header|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. |
The following is based on the Java entry but dispenses with the grid and slider as these aren't really part of the task. |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
import java.awt.* |
import java.awt.* |
||
Line 548: | Line 902: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Lambdatalk}}== |
|||
Drawing four super-ellipses, a circle, a rounded square, a square, an astroid. |
|||
<syntaxhighlight lang="scheme"> |
|||
{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 |
|||
</syntaxhighlight> |
|||
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. |
|||
<syntaxhighlight lang="scheme"> |
|||
{{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}}} |
|||
}} |
|||
</syntaxhighlight> |
|||
The output can be seen in http://lambdaway.free.fr/lambdawalks/?view=super_ellipse |
|||
=={{header|Liberty BASIC}}== |
|||
Reworked the Julia version to work and added a loop with a spread on n values. |
|||
<syntaxhighlight lang="lb"> |
|||
[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 |
|||
</syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
Scale of a and b were reduced to facilitate an ASCII solution: |
|||
<syntaxhighlight lang="lua">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()</syntaxhighlight> |
|||
{{out}} |
|||
<pre style="font-size:25%">................................................................................................................................................................ |
|||
..........................................................[][][][][][][][][][][][][][][][][][][][][]............................................................ |
|||
............................................[][][][][][][]..........................................[][][][][][][].............................................. |
|||
......................................[][][][]..................................................................[][][][]........................................ |
|||
................................[][][][]..............................................................................[][][][].................................. |
|||
............................[][][]..........................................................................................[][][].............................. |
|||
........................[][][]..................................................................................................[][][].......................... |
|||
......................[][]..........................................................................................................[][]........................ |
|||
..................[][]..................................................................................................................[][].................... |
|||
................[][]......................................................................................................................[][].................. |
|||
..............[][]..........................................................................................................................[][]................ |
|||
............[][]..............................................................................................................................[][].............. |
|||
............[]..................................................................................................................................[].............. |
|||
..........[]......................................................................................................................................[]............ |
|||
........[][]......................................................................................................................................[][].......... |
|||
........[]..........................................................................................................................................[].......... |
|||
......[]..............................................................................................................................................[]........ |
|||
......[]..............................................................................................................................................[]........ |
|||
....[][]..............................................................................................................................................[][]...... |
|||
....[]..................................................................................................................................................[]...... |
|||
....[]..................................................................................................................................................[]...... |
|||
....[]..................................................................................................................................................[]...... |
|||
..[][]..................................................................................................................................................[][].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[]......................................................................................................................................................[].... |
|||
..[][]..................................................................................................................................................[][].... |
|||
....[]..................................................................................................................................................[]...... |
|||
....[]..................................................................................................................................................[]...... |
|||
....[]..................................................................................................................................................[]...... |
|||
....[][]..............................................................................................................................................[][]...... |
|||
......[]..............................................................................................................................................[]........ |
|||
......[]..............................................................................................................................................[]........ |
|||
........[]..........................................................................................................................................[].......... |
|||
........[][]......................................................................................................................................[][].......... |
|||
..........[]......................................................................................................................................[]............ |
|||
............[]..................................................................................................................................[].............. |
|||
............[][]..............................................................................................................................[][].............. |
|||
..............[][]..........................................................................................................................[][]................ |
|||
................[][]......................................................................................................................[][].................. |
|||
..................[][]..................................................................................................................[][].................... |
|||
......................[][]..........................................................................................................[][]........................ |
|||
........................[][][]..................................................................................................[][][].......................... |
|||
............................[][][]..........................................................................................[][][].............................. |
|||
................................[][][][]..............................................................................[][][][].................................. |
|||
......................................[][][][]..................................................................[][][][]........................................ |
|||
............................................[][][][][][][]..........................................[][][][][][][].............................................. |
|||
..........................................................[][][][][][][][][][][][][][][][][][][][][]............................................................ |
|||
................................................................................................................................................................ |
|||
................................................................................................................................................................ |
|||
</pre> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
The built-in command ImplicitPlot accepts an equation in 2 variables: |
The built-in command ImplicitPlot accepts an equation in 2 variables: |
||
< |
<syntaxhighlight lang="maple">plots:-implicitplot(abs((1/200)*x^2.5)+abs((1/200)*y^2.5) = 1, x = -10 .. 10, y = -10 .. 10);</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
The built-in function ContourPlot accepts an equation in 2 variables and creates the desired plot |
|||
<syntaxhighlight lang="mathematica">ContourPlot[Abs[x/200]^2.5 + Abs[y/200]^2.5 == 1, {x, -200, 200}, {y, -200, 200}]</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
{{libheader|imageman}} |
|||
<syntaxhighlight lang="nim">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) |
|||
=={{header|Mathematica}}== |
|||
image.fill(Background) |
|||
The built-in function ContourPlot accepts and equation in 2 variables and creates the |
|||
image.drawSuperEllipse(2.5, 200, 200) |
|||
desired plot |
|||
image.savePNG("super_ellipse.png", compression = 9)</syntaxhighlight> |
|||
<lang Mathematica>ContourPlot[ |
|||
Abs[x/200]^2.5 + Abs[y/200]^2.5 == 1, {x, -200, 200}, {y, -200, 200}]</lang> |
|||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
Line 568: | Line 1,153: | ||
black 280,280,4</pre> |
black 280,280,4</pre> |
||
< |
<syntaxhighlight lang="oorexx">/* REXX *************************************************************** |
||
* Create a BMP file showing a few super ellipses |
* Create a BMP file showing a few super ellipses |
||
**********************************************************************/ |
**********************************************************************/ |
||
Line 644: | Line 1,229: | ||
Return |
Return |
||
::requires rxMath library</ |
::requires rxMath library</syntaxhighlight> |
||
=={{header|Perl |
=={{header|Perl}}== |
||
{{trans|Raku}} |
|||
{{works with|rakudo|2016-01}} |
|||
<syntaxhighlight lang="perl">use v5.36; |
|||
Generate an svg image to STDOUT. Redirect into a file to capture it. |
|||
my($a, $b, $n, @q) = (200, 200, 2.5); |
|||
<lang perl6>constant a = 200; |
|||
constant b = 200; |
|||
constant n = 2.5; |
|||
# y in terms of x |
# y in terms of x |
||
sub |
sub y_from_x ($x) { int $b * abs(1 - ($x/$a) ** $n ) ** (1/$n) } |
||
# find point pairs for one quadrant |
# find point pairs for one quadrant |
||
push @q, $_, y_from_x($_) for 0..$a; |
|||
open $fh, '>', 'superellipse.svg'; |
|||
# Generate an SVG image |
|||
print $fh |
|||
INIT say qq:to/STOP/; |
|||
qq|<svg height="@{[2*$b]}" width="@{[2*$a]}" xmlns="http://www.w3.org/2000/svg">\n|, |
|||
<?xml version="1.0" standalone="no"?> |
|||
pline( 1, 1, @q ), |
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
|||
pline( 1,-1, @q ), # flip and mirror |
|||
<svg height="{b*2}" width="{a*2}" version="1.1" xmlns="http://www.w3.org/2000/svg"> |
|||
pline(-1,-1, @q ), # for the other |
|||
STOP |
|||
pline(-1, 1, @q ), # three quadrants |
|||
END say '</svg>'; |
|||
'</svg>'; |
|||
sub pline ($sx, $sy, @q) { |
|||
.put for |
|||
(@q[2*$_] *= $sx, @q[1+2*$_] *= $sy) for 0 .. $#q/2; |
|||
pline( @q ), |
|||
qq|<polyline points="@q" |
|||
pline( @q «*» ( 1,-1) ), # flip and mirror |
|||
style="fill:none;stroke:black;stroke-width:3" |
|||
pline( @q «*» (-1,-1) ), # for the other |
|||
transform="translate($a, $b)" />\n| |
|||
pline( @q «*» (-1, 1) ); # three quadrants |
|||
}</syntaxhighlight> |
|||
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/superellipse.svg Superellipse] (offsite image) |
|||
=={{header|Phix}}== |
|||
sub pline (@q) { |
|||
{{libheader|Phix/pGUI}} |
|||
qq:to/END/; |
|||
{{libheader|Phix/online}} |
|||
<polyline points="{@q}" |
|||
You can run this online [http://phix.x10.mx/p2js/Superellipse.htm here]. |
|||
style="fill:none; stroke:black; stroke-width:3" transform="translate({a}, {b})" /> |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
END |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
}</lang> |
|||
-- demo\rosetta\Superellipse.exw |
|||
See [https://gist.github.com/thundergnat/cc41a5fae7021803496c#file-superellipse-svg Superellipse image] |
|||
-- ============================= |
|||
--</span> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2.5</span> <span style="color: #000080;font-style:italic;">-- '+' and '-' increase/decrease in steps of 0.1</span> |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span> |
|||
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">h</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">hw</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">hh</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">h</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hw</span><span style="color: #0000FF;">-</span><span style="color: #000000;">100</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- (initially 200, from 602x )</span> |
|||
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">50</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (initially 200, from x502)</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">exp</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">log</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">/</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">))/</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasBegin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_OPEN_LINES</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- starting point</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">a</span> <span style="color: #008080;">to</span> <span style="color: #000000;">0</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hh</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">a</span> <span style="color: #008080;">do</span> <span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hh</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">a</span> <span style="color: #008080;">to</span> <span style="color: #000000;">0</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #7060A8;">cdCanvasVertex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #7060A8;">cdCanvasEnd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">130</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (otherwise [>130] power overflow)</span> |
|||
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (otherwise [=0.0] divide by zero)</span> |
|||
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=602x502"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">)})</span> |
|||
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE=Superellipse"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"KEY_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- release the minimum limitation</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span> |
|||
<!--</syntaxhighlight>--> |
|||
=={{header|Processing}}== |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="java"> |
|||
//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); |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang="python"> |
||
# Superellipse drawing in Python 2.7.9 |
# Superellipse drawing in Python 2.7.9 |
||
# pic can see at http://www.imgup.cz/image/712 |
# pic can see at http://www.imgup.cz/image/712 |
||
Line 709: | Line 1,396: | ||
plt.title("Superellipse with parameter "+str(n)) |
plt.title("Superellipse with parameter "+str(n)) |
||
plt.show() |
plt.show() |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|QB64}}== |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
=={{header|QBasic}}== |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(require plot) |
(require plot) |
||
#;(plot-new-window? #t) |
#;(plot-new-window? #t) |
||
Line 721: | Line 1,466: | ||
(plot (isoline (superellipse 200 200 2.5) 1 |
(plot (isoline (superellipse 200 200 2.5) 1 |
||
-220 220 -220 220))</ |
-220 220 -220 220))</syntaxhighlight> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>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| |
|||
}</syntaxhighlight> |
|||
[https://github.com/SqrtNegInf/Rosettacode-Perl6-Smoke/blob/master/ref/superellipse.svg Superellipse] (offsite image) |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 727: | Line 1,497: | ||
Here you can see a picture: http://austria-forum.org/af/User/Pachl%20Walter |
Here you can see a picture: http://austria-forum.org/af/User/Pachl%20Walter |
||
< |
<syntaxhighlight lang="rexx">/* REXX *************************************************************** |
||
* Create a BMP file showing a few super ellipses |
* Create a BMP file showing a few super ellipses |
||
**********************************************************************/ |
**********************************************************************/ |
||
Line 888: | Line 1,658: | ||
r=r/ln(b) |
r=r/ln(b) |
||
Numeric Digits (prec) |
Numeric Digits (prec) |
||
Return r+0</ |
Return r+0</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
===Java Swing Interoperability=== |
===Java Swing Interoperability=== |
||
< |
<syntaxhighlight lang="scala">import java.awt._ |
||
import java.awt.geom.Path2D |
import java.awt.geom.Path2D |
||
import java.util |
import java.util |
||
Line 995: | Line 1,765: | ||
}) |
}) |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans| |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="ruby">const ( |
||
a = 200, |
a = 200, |
||
b = 200, |
b = 200, |
||
Line 1,031: | Line 1,802: | ||
].each { .print } |
].each { .print } |
||
say '</svg>'</ |
say '</svg>'</syntaxhighlight> |
||
=={{header|Stata}}== |
=={{header|Stata}}== |
||
< |
<syntaxhighlight lang="stata">sca a=200 |
||
sca b=200 |
sca b=200 |
||
sca n=2.5 |
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)</ |
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)</syntaxhighlight> |
||
=={{header|Wren}}== |
|||
{{libheader|DOME}} |
|||
Uses Go's drawing code but produces a more complex image. |
|||
<syntaxhighlight lang="wren">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) |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|XPL0}}== |
|||
<syntaxhighlight lang="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; |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://www.xpl0.org/rcell.gif |
|||
</pre> |
|||
=={{header|Yabasic}}== |
|||
<syntaxhighlight lang="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</syntaxhighlight> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl |
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl |
||
[[File:SuperEllipse.zkl.jpg|250px|thumb|right]] |
[[File:SuperEllipse.zkl.jpg|250px|thumb|right]] |
||
< |
<syntaxhighlight lang="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 |
a,p:=(plot.w/2).toFloat(), 1.0/n; // just calculate upper right quadrant |
||
foreach x in ([0.0 .. a]){ |
foreach x in ([0.0 .. a]){ |
||
Line 1,051: | Line 1,931: | ||
} |
} |
||
plot |
plot |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">w:=h:=600; |
||
plot:=PPM(w+1,h+1,0x909090); plot.cross(w/2,h/2); |
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 ([0.01..1, 0.14]){ superEllipse(plot,n, 0x0000bb) }// 0-1: blue |
||
Line 1,058: | Line 1,938: | ||
foreach n in ([2.0..10, 1.4]) { superEllipse(plot,n, 0xff0000) }// 2+: red |
foreach n in ([2.0..10, 1.4]) { superEllipse(plot,n, 0xff0000) }// 2+: red |
||
plot.writeJPGFile("superEllipse.jpg");</ |
plot.writeJPGFile("superEllipse.jpg");</syntaxhighlight> |
Latest revision as of 12:54, 11 February 2024
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
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:
Screenshot from Atari 8-bit computer
Ada
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
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
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
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
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
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
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
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
//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
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
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
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");
- Programming Tasks
- Solutions by Programming Task
- Action!
- Action! Tool Kit
- Ada
- SDLAda
- AutoHotkey
- C
- Delphi
- SysUtils,StdCtrls
- EasyLang
- EchoLisp
- FreeBASIC
- Go
- Go Graphics
- Haskell
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Lambdatalk
- Liberty BASIC
- Lua
- Maple
- Mathematica
- Wolfram Language
- Nim
- Imageman
- OoRexx
- Perl
- Phix
- Phix/pGUI
- Phix/online
- Processing
- Python
- QB64
- QBasic
- Racket
- Raku
- REXX
- Scala
- Sidef
- Stata
- Wren
- DOME
- XPL0
- Yabasic
- Zkl