Barnsley fern

From Rosetta Code
Revision as of 15:53, 1 March 2016 by rosettacode>Fwend (→‎{{headerJava}}: added Java)
Barnsley fern 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 Barnsley fern is a fractal named after British mathematician Michael Barnsley and can be created using an iterated function system (IFS).


The task: create this fractal fern, using the following transformations:

  • ƒ1 (chosen 1% of the time)
   xn + 1 = 0
   yn + 1 = 0.16 yn
  • ƒ2 (chosen 85% of the time)
   xn + 1 = 0.85 xn + 0.04 yn
   yn + 1 = −0.04 xn + 0.85 yn + 1.6
  • ƒ3 (chosen 7% of the time)
   xn + 1 = 0.2 xn − 0.26 yn
   yn + 1 = 0.23 xn + 0.22 yn + 1.6
  • ƒ4 (chosen 7% of the time)
   xn + 1 = −0.15 xn + 0.28 yn
   yn + 1 = 0.26 xn + 0.24 yn + 0.44.

Starting position: x = 0, y = 0


Java

Works with: Java version 8

<lang java>import java.awt.*; import javax.swing.*;

public class BarnsleyFern extends JPanel {

   public BarnsleyFern() {
       Dimension dim = new Dimension(640, 640);
       setPreferredSize(dim);
       setBackground(Color.white);
       setForeground(Color.green.darker());
   }
   void drawFern(Graphics2D g) {
       double w = getWidth();
       double h = getHeight();
       double x = 0;
       double y = 0;
       for (int i = 0; i < 200_000; i++) {
           double tmpx, tmpy;
           double r = Math.random();
           if (r <= 0.01) {
               tmpx = 0;
               tmpy = 0.16 * y;
           } else if (r <= 0.08) {
               tmpx = 0.2 * x - 0.26 * y;
               tmpy = 0.23 * x + 0.22 * y + 1.6;
           } else if (r <= 0.15) {
               tmpx = -0.15 * x + 0.28 * y;
               tmpy = 0.26 * x + 0.24 * y + 0.44;
           } else {
               tmpx = 0.85 * x + 0.04 * y;
               tmpy = -0.04 * x + 0.85 * y + 1.6;
           }
           x = tmpx;
           y = tmpy;
           g.fillOval((int) Math.round(w / 2 + x * 60),
                   (int) Math.round(h - y * 60), 1, 1);
       }
   }
   @Override
   public void paintComponent(Graphics gg) {
       super.paintComponent(gg);
       Graphics2D g = (Graphics2D) gg;
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
       drawFern(g);
   }
   public static void main(String[] args) {
       SwingUtilities.invokeLater(() -> {
           JFrame f = new JFrame();
           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           f.setTitle("Barnsley Fern");
           f.setResizable(false);
           f.add(new BarnsleyFern(), BorderLayout.CENTER);
           f.pack();
           f.setLocationRelativeTo(null);
           f.setVisible(true);
       });
   }

}</lang>