Superellipse

From Rosetta Code
Revision as of 05:36, 17 October 2015 by Walterpachl (talk | contribs) (add ooRexx)
Superellipse is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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

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

Works with: Java version 8

<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>