Superellipse
A superellipse is a geometric figure defined as the set of all points (x, y) with
- Failed to parse (SVG (MathML can be enabled via browser plugin): Invalid response ("Math extension cannot connect to Restbase.") from server "https://wikimedia.org/api/rest_v1/":): {\displaystyle \left|\frac{x}{a}\right|^n\! + \left|\frac{y}{b}\right|^n\! = 1,}
where n, a and b are positive numbers.
The task: draw a superellipse with n = 2.5, and a = b = 200
EchoLisp
Link to the super-ellipse image. <lang scheme> (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))
</lang>
J
We will fill the ellipse so that we do not have to worry about the size and shape of our pixels:
<lang J>selips=: 4 :0
'n a b'=. y 1 >: ((n^~a%~]) +&|/ n^~b%~]) i:x
)
require'viewmat' viewmat 300 selips 2.5 200 200</lang>
rosettacode does not currently support image uploads, so you'll just have to imagine what it looks like (or run the code yourself).
Java
<lang 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); }); }
}</lang>
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
<lang oorexx>/* 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</lang>
REXX
<lang rexx>/* 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,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-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