Barnsley fern

From Rosetta Code
Revision as of 22:21, 31 July 2016 by rosettacode>Fwend (→‎{{header|tcl}}: not an implementation of the task)
Task
Barnsley fern
You are encouraged to solve this task according to the task description, using any language you may know.

A Barnsley fern is a fractal named after British mathematician Michael Barnsley and can be created using an iterated function system (IFS).


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

C++

<lang cpp>

  1. include <windows.h>
  2. include <ctime>
  3. include <string>

const int BMP_SIZE = 600, ITERATIONS = static_cast<int>( 15e5 );

class myBitmap { public:

   myBitmap() : pen( NULL ), brush( NULL ), clr( 0 ), wid( 1 ) {}
   ~myBitmap() {
       DeleteObject( pen ); DeleteObject( brush );
       DeleteDC( hdc ); DeleteObject( bmp );
   }
   bool create( int w, int h ) {
       BITMAPINFO bi;
       ZeroMemory( &bi, sizeof( bi ) );
       bi.bmiHeader.biSize        = sizeof( bi.bmiHeader );
       bi.bmiHeader.biBitCount    = sizeof( DWORD ) * 8;
       bi.bmiHeader.biCompression = BI_RGB;
       bi.bmiHeader.biPlanes      = 1;
       bi.bmiHeader.biWidth       =  w;
       bi.bmiHeader.biHeight      = -h;
       HDC dc = GetDC( GetConsoleWindow() );
       bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
       if( !bmp ) return false;
       hdc = CreateCompatibleDC( dc );
       SelectObject( hdc, bmp );
       ReleaseDC( GetConsoleWindow(), dc );
       width = w; height = h;
       return true;
   }
   void clear( BYTE clr = 0 ) {
       memset( pBits, clr, width * height * sizeof( DWORD ) );
   }
   void setBrushColor( DWORD bClr ) {
       if( brush ) DeleteObject( brush );
       brush = CreateSolidBrush( bClr );
       SelectObject( hdc, brush );
   }
   void setPenColor( DWORD c ) {
       clr = c; createPen();
   }
   void setPenWidth( int w ) {
       wid = w; createPen();
   }
   void saveBitmap( std::string path ) {
       BITMAPFILEHEADER fileheader;
       BITMAPINFO       infoheader;
       BITMAP           bitmap;
       DWORD            wb;
       GetObject( bmp, sizeof( bitmap ), &bitmap );
       DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
       ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
       ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
       ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );
       infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
       infoheader.bmiHeader.biCompression = BI_RGB;
       infoheader.bmiHeader.biPlanes = 1;
       infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
       infoheader.bmiHeader.biHeight = bitmap.bmHeight;
       infoheader.bmiHeader.biWidth = bitmap.bmWidth;
       infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );
       fileheader.bfType    = 0x4D42;
       fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
       fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;
       GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );
       HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 
           FILE_ATTRIBUTE_NORMAL, NULL );
       WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
       WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
       WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
       CloseHandle( file );
       delete [] dwpBits;
   }
   HDC getDC() const     { return hdc; }
   int getWidth() const  { return width; }
   int getHeight() const { return height; }

private:

   void createPen() {
       if( pen ) DeleteObject( pen );
       pen = CreatePen( PS_SOLID, wid, clr );
       SelectObject( hdc, pen );
   }
   HBITMAP bmp; HDC    hdc;
   HPEN    pen; HBRUSH brush;
   void    *pBits; int    width, height, wid;
   DWORD    clr;

}; class fern { public:

   void draw() {
       bmp.create( BMP_SIZE, BMP_SIZE );
       float x = 0, y = 0; HDC dc = bmp.getDC();
       int hs = BMP_SIZE >> 1;
       for( int f = 0; f < ITERATIONS; f++ ) {
           SetPixel( dc, hs + static_cast<int>( x * 55.f ), 
                     BMP_SIZE - 15 - static_cast<int>( y * 55.f ), 
                     RGB( static_cast<int>( rnd() * 80.f ) + 20, 
                          static_cast<int>( rnd() * 128.f ) + 128, 
                          static_cast<int>( rnd() * 80.f ) + 30 ) ); 
           getXY( x, y );
       }
       bmp.saveBitmap( "./bf.bmp" );
   }

private:

   void getXY( float& x, float& y ) {
       float g, xl, yl;
       g = rnd();
       if( g < .01f ) { xl = 0; yl = .16f * y; } 
       else if( g < .07f ) {
           xl = .2f * x - .26f * y;
           yl = .23f * x + .22f * y + 1.6f;
       } else if( g < .14f ) {
           xl = -.15f * x + .28f * y;
           yl = .26f * x + .24f * y + .44f;
       } else {
           xl = .85f * x + .04f * y;
           yl = -.04f * x + .85f * y + 1.6f;
       }
       x = xl; y = yl;
   }
   float rnd() {
       return static_cast<float>( rand() ) / static_cast<float>( RAND_MAX );
   }
   myBitmap bmp;

}; int main( int argc, char* argv[]) {

   srand( static_cast<unsigned>( time( 0 ) ) );
   fern f; f.draw(); return 0;    

} </lang>

Delphi

Translation of: Java

Hint: After putting a TPaintBox on the main form align it to alClient. Client width / heigth of the main form should be no less than 640 x 480. <lang delphi>unit Unit1;

interface

uses

 Windows, SysUtils, Graphics, Forms, Controls, Classes, ExtCtrls;

type

 TForm1 = class(TForm)
   PaintBox1: TPaintBox;
   procedure FormPaint(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var

 Form1: TForm1;

implementation

{$R *.dfm}

procedure CreateFern(const w, h: integer); var r, x, y: double;

   tmpx, tmpy: double;
   i: integer;

begin

   x := 0;
   y := 0;
   randomize();
   for i := 0 to 200000 do begin
       r := random(100000000) / 99999989;
       if r <= 0.01 then begin
           tmpx := 0;
           tmpy := 0.16 * y;
       end
       else if r <= 0.08 then begin
           tmpx := 0.2 * x - 0.26 * y;
           tmpy := 0.23 * x + 0.22 * y + 1.6;
       end
       else if r <= 0.15 then begin
           tmpx := -0.15 * x + 0.28 * y;
           tmpy := 0.26 * x + 0.24 * y + 0.44;
       end
       else begin
           tmpx := 0.85 * x + 0.04 * y;
           tmpy := -0.04 * x + 0.85 * y + 1.6;
       end;
       x := tmpx;
       y := tmpy;
       Form1.PaintBox1.Canvas.Pixels[round(w / 2 + x * w / 11), round(h - y * h / 11)] := clGreen;
   end;

end;

procedure TForm1.FormPaint(Sender: TObject); begin

   CreateFern(Form1.ClientWidth, Form1.ClientHeight);

end;

end.</lang>

Go

<lang go>package main

import (

   "image"
   "image/color"
   "image/draw"
   "image/png"
   "log"
   "math/rand"
   "os"

)

// values from WP const (

   xMin = -2.1820
   xMax = 2.6558
   yMin = 0.
   yMax = 9.9983

)

// parameters var (

   width = 200
   n     = int(1e6)
   c     = color.RGBA{34, 139, 34, 255} // forest green

)

func main() {

   dx := xMax - xMin
   dy := yMax - yMin
   fw := float64(width)
   fh := fw * dy / dx
   height := int(fh)
   r := image.Rect(0, 0, width, height)
   img := image.NewRGBA(r)
   draw.Draw(img, r, &image.Uniform{color.White}, image.ZP, draw.Src)
   var x, y float64
   plot := func() {
       // transform computed float x, y to integer image coordinates
       ix := int(fw * (x - xMin) / dx)
       iy := int(fh * (yMax - y) / dy)
       img.SetRGBA(ix, iy, c)
   }
   plot()
   for i := 0; i < n; i++ {
       switch s := rand.Intn(100); {
       case s < 85:
           x, y =
               .85*x+.04*y,
               -.04*x+.85*y+1.6
       case s < 85+7:
           x, y =
               .2*x-.26*y,
               .23*x+.22*y+1.6
       case s < 85+7+7:
           x, y =
               -.15*x+.28*y,
               .26*x+.24*y+.44
       default:
           x, y = 0, .16*y
       }
       plot()
   }
   // write img to png file
   f, err := os.Create("bf.png")
   if err != nil {
       log.Fatal(err)
   }
   if err := png.Encode(f, img); err != nil {
       log.Fatal(err)
   }

}</lang>

Haskell

<lang haskell>import Data.List (scanl') import Diagrams.Backend.Rasterific.CmdLine import Diagrams.Prelude import System.Random

type Pt = (Double, Double)

-- Four affine transformations used to produce a Barnsley fern. f1, f2, f3, f4 :: Pt -> Pt f1 (x, y) = ( 0, 0.16 * y) f2 (x, y) = ( 0.85 * x + 0.04 * y , -0.04 * x + 0.85 * y + 1.60) f3 (x, y) = ( 0.20 * x - 0.26 * y , 0.23 * x + 0.22 * y + 1.60) f4 (x, y) = (-0.15 * x + 0.28 * y , 0.26 * x + 0.24 * y + 0.44)

-- Given a random number in [0, 1) transform an initial point by a randomly -- chosen function. func :: Pt -> Double -> Pt func p r | r < 0.01 = f1 p

        | r < 0.86  = f2 p
        | r < 0.93  = f3 p
        | otherwise = f4 p

-- Using a sequence of uniformly distributed random numbers in [0, 1) return -- the same number of points in the fern. fern :: [Double] -> [Pt] fern = scanl' func (0, 0)

-- Given a supply of random values and a count, generate a diagram of a fern -- composed of that number of points. drawFern :: [Double] -> Int -> Diagram B drawFern rs n = frame 0.5 . diagramFrom . take n $ fern rs

 where diagramFrom = flip atPoints (repeat dot) . map p2
       dot = circle 0.005 # lc green

-- To generate a PNG image of a fern, call this program like: -- -- fern -o fern.png -w 640 -h 640 50000 -- -- where the arguments specify the width, height and number of points in the -- image. main :: IO () main = do

 rand <- getStdGen
 mainWith $ drawFern (randomRs (0, 1) rand)</lang>

J

<lang j>require 'plot'

f=: |: 0 ". ];._2 noun define

 0     0     0    0.16   0 0      0.01
 0.85 -0.04  0.04 0.85   0 1.60   0.85
 0.20  0.23 -0.26 0.22   0 1.60   0.07
-0.15  0.26  0.28 0.24   0 0.44   0.07

)

fm=: {&(|: 2 2 $ f) fa=: {&(|: 4 5 { f) prob=: (+/\ 6 { f) I. ?@0:

ifs=: (fa@] + fm@] +/ .* [) prob getPoints=: ifs^:(<200000) plotFern=: 'dot;grids 0 0;tics 0 0;labels 0 0;color green' plot ;/@|:

  plotFern getPoints 0 0</lang>

Java

Works with: Java version 8

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

public class BarnsleyFern extends JPanel {

   BufferedImage img;
   public BarnsleyFern() {
       final int dim = 640;
       setPreferredSize(new Dimension(dim, dim));
       setBackground(Color.white);
       img = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_ARGB);
       createFern(dim, dim);
   }
   void createFern(int w, int h) {
       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;
           img.setRGB((int) Math.round(w / 2 + x * w / 11),
                   (int) Math.round(h - y * h / 11), 0xFF32CD32);
       }
   }
   @Override
   public void paintComponent(Graphics gg) {
       super.paintComponent(gg);
       Graphics2D g = (Graphics2D) gg;
       g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
       g.drawImage(img, 0, 0, null);
   }
   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>

JavaScript

Translation of: PARI/GP
File:BarnsleyFernjs.png
Output BarnsleyFernjs.png

<lang javascript> // Barnsley fern fractal //6/17/16 aev function pBarnsleyFern(canvasId,lim) {

 // DCLs
 var canvas = document.getElementById(canvasId);
 var ctx = canvas.getContext("2d");
 var w = canvas.width;
 var h = canvas.height;
 var x=0.,y=0.,xw=0.,yw=0.,r;
 // Like in PARI/GP: return random number 0..max-1
 function randgp(max) {return Math.floor(Math.random()*max)}
 // Clean canvas
 ctx.fillStyle="white"; ctx.fillRect(0,0,w,h);
 // MAIN LOOP
 for(var i=0; i<lim; i++) {
   r=randgp(100);
   if (r<=1) {xw=0;yw=0.16*y;}
   else if (r<=8) {xw=0.2*x-0.26*y;yw=0.23*x+0.22*y+1.6;}
   else if (r<=15) {xw=-0.15*x+0.28*y;yw=0.26*x+0.24*y+0.44;}
   else {xw=0.85*x+0.04*y;yw=-0.04*x+0.85*y+1.6;}
   x=xw;y=yw; ctx.fillStyle="green"; ctx.fillRect(x*50+260,-y*50+540,1,1);
 }//fend i

} </lang> Executing: <lang html> <html>

<head><script src="BarnsleyFern.js"></script></head>
<body onload="pBarnsleyFern('canvas', 100000)">


Barnsley fern fractal

  <canvas id="canvas" width="540" height="540" style="border: 2px inset;"></canvas>
</body>

</html> </lang>

Output:
Page with BarnsleyFernjs.png

PARI/GP

Translation of: zkl
Works with: PARI/GP version 2.7.4 and above
File:BarnsleyFern.png
Output BarnsleyFern.png

<lang parigp> \\ Barnsley fern fractal \\ 6/17/16 aev pBarnsleyFern(size,lim)={ my(X=List(),Y=X,x=y=xw=yw=0.0,r); print(" *** Barnsley Fern, size=",size," lim=",lim); plotinit(0); plotcolor(0,6); \\green plotscale(0, -3,3, 0,10); plotmove(0, 0,0); for(i=1, lim,

 r=random(100);
 if(r<=1, xw=0;yw=0.16*y,
   if(r<=8, xw=0.2*x-0.26*y;yw=0.23*x+0.22*y+1.6,
     if(r<=15, xw=-0.15*x+0.28*y;yw=0.26*x+0.24*y+0.44,
       xw=0.85*x+0.04*y;yw=-0.04*x+0.85*y+1.6)));
 x=xw;y=yw; listput(X,x); listput(Y,y);

);\\fend i plotpoints(0,Vec(X),Vec(Y)); plotdraw([0,-3,-0]); } {\\ Executing: pBarnsleyFern(530,100000); \\ BarnsleyFern.png } </lang>

Output:
> pBarnsleyFern(530,100000);  \\ BarnsleyFern.png
 *** Barnsley Fern, size=530 lim=100000

Perl

<lang perl>use Imager;

my $w = 640; my $h = 640;

my $img = Imager->new(xsize => $w, ysize => $h, channels => 3); my $green = Imager::Color->new('#00FF00');

my ($x, $y) = (0, 0);

foreach (1 .. 2e5) {

 my $r = rand(100);
 ($x, $y) = do {
   if    ($r <=  1) { ( 0.00 * $x - 0.00 * $y,  0.00 * $x + 0.16 * $y + 0.00) }
   elsif ($r <=  8) { ( 0.20 * $x - 0.26 * $y,  0.23 * $x + 0.22 * $y + 1.60) }
   elsif ($r <= 15) { (-0.15 * $x + 0.28 * $y,  0.26 * $x + 0.24 * $y + 0.44) }
   else             { ( 0.85 * $x + 0.04 * $y, -0.04 * $x + 0.85 * $y + 1.60) }
 };
 $img->setpixel(x => $w / 2 + $x * 60, y => $y * 60, color => $green);

}

$img->flip(dir => 'v'); $img->write(file => 'barnsleyFern.png');</lang>

Perl 6

Works with: Rakudo version 2016.03
Translation of: Perl

<lang perl6>use Image::PNG::Portable;

my ($w, $h) = (640, 640);

my $png = Image::PNG::Portable.new: :width($w), :height($h);

my ($x, $y) = (0, 0);

for ^2e5 {

   my $r = 100.rand;
   ($x, $y) = do given $r {
       when  $r <=  1 { (                     0,              0.16 * $y       ) }
       when  $r <=  8 { ( 0.20 * $x - 0.26 * $y,  0.23 * $x + 0.22 * $y + 1.60) }
       when  $r <= 15 { (-0.15 * $x + 0.28 * $y,  0.26 * $x + 0.24 * $y + 0.44) }
       default        { ( 0.85 * $x + 0.04 * $y, -0.04 * $x + 0.85 * $y + 1.60) }
   };
   $png.set(($w / 2 + $x * 60).Int, $h - ($y * 60).Int, 0, 255, 0);

}

$png.write: 'Barnsley-fern-perl6.png';</lang>

Phix

This file is included in the distro as demo\rosetta\BarnsleyFern.exw

File:PhixBarnsleyFern.png

<lang Phix>include ..\pGUI\pGUI.e

Ihandle dlg, canvas cdCanvas cddbuffer, cdcanvas

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/) atom {x,y,r} @= 0 integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")

   cdCanvasActivate(cddbuffer)
   for i=1 to 20000 do
       r = rand(100)
       {x, y} = iff(r<=1? {             0,        0.16*y     } :
                iff(r<=8? { 0.20*x-0.26*y, 0.23*x+0.22*y+1.60} :
                iff(r<=15?{-0.15*x+0.28*y, 0.26*x+0.24*y+0.44} :
                          { 0.85*x+0.04*y,-0.04*x+0.85*y+1.60})))
       cdCanvasPixel(cddbuffer, width/2+x*60, y*60, #00FF00) 
   end for
   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_RED)
   return IUP_DEFAULT

end function

function esc_close(Ihandle /*ih*/, atom c)

   if c=K_ESC then return IUP_CLOSE end if
   return IUP_CONTINUE

end function

procedure main()

   IupOpen("..\\pGUI\\")
   canvas = IupCanvas(NULL)
   IupSetAttribute(canvas, "RASTERSIZE", "340x620") -- initial size
   IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
   dlg = IupDialog(canvas)
   IupSetAttribute(dlg, "TITLE", "Barnsley Fern")
   IupSetCallback(dlg, "K_ANY",     Icallback("esc_close"))
   IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
   IupMap(dlg)
   IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
   IupShowXY(dlg,IUP_CENTER,IUP_CENTER)
   IupMainLoop()
   IupClose()

end procedure

main()</lang>

Processing

<lang java>void setup() {

 size(640, 640);
 background(0, 0, 0);

}

float x = 0; float y = 0;

void draw() {

 for (int i = 0; i < 100000; i++) {
   float xt = 0;
   float yt = 0;
   float r = random(100);
   if (r <= 1) {
     xt = 0;
     yt = 0.16*y;
   } else if (r <= 8) {
     xt = 0.20*x - 0.26*y;
     yt = 0.23*x + 0.22*y + 1.60;
   } else if (r <= 15) {
     xt = -0.15*x + 0.28*y;
     yt =  0.26*x + 0.24*y + 0.44;
   } else {
     xt =  0.85*x + 0.04*y;
     yt = -0.04*x + 0.85*y + 1.60;
   }
   x = xt;
   y = yt;
   int m = round(width/2 + 60*x);
   int n = height-round(60*y);
   set(m, n, #00ff00);
 }
 noLoop();

}</lang>


Ring

<lang Ring>

Load "guilib.ring"

/*

+---------------------------------------------------------------------------
+        Program Name : Draw Barnsley Fern
+        Date         : 2016.06.12
+        Author       : Bert Mariani
+        Purpose      : Draw Fern using Quadratic Equation and Random Number
+---------------------------------------------------------------------------
  • /
      1. -------------------------------
      2. DRAW CHART size 400 x 500
      3. -------------------------------


New qapp { win1 = new qwidget() { ### Position and Size on Screen setwindowtitle("Drawing using QPainter") setgeometry( 10, 25, 400, 500)

### Draw within this Win Box label1 = new qlabel(win1) { ### Label Position and Size setgeometry(10, 10, 400, 500) settext(" ") }

buttonFern = new qpushbutton(win1) { ### Button DrawFern setgeometry(10, 10, 80, 20) settext("Draw Fern") setclickevent("DrawFern()") ### Call DRAW function }

show() } exec() }

      1. ------------------------
      2. FUNCTIONS
      3. ------------------------

Func DrawFern p1 = new qpicture()

colorGreen = new qcolor() { setrgb(0,255,0,255) } penGreen = new qpen() { setcolor(colorGreen) setwidth(1) }

new qpainter() { begin(p1) setpen(penGreen)

###------------------------------------- ### Quadratic equation matrix of arrays

a = [ 0, 0.85, 0.2, -0.15 ] b = [ 0, 0.04, -0.26, 0.28 ] c = [ 0, -0.04, 0.23, 0.26 ] d = [ 0.16, 0.85, 0.22, 0.24 ] e = [ 0, 0, 0, 0 ] f = [ 0, 1.6, 1.6, 0.44 ]

### Initialize x, y points

xf = 0.0 yf = 0.0

### Size of output screen

MaxX = 400 MaxY = 500 MaxIterations = MaxY * 200 Count = 0

###------------------------------------------------

while ( Count <= MaxIterations )

### NOTE *** RING *** starts at Index 1, ### Do NOT use Random K=0 result

k = random() % 100 k = k +1

### if (k = 0) k = 1 ok ### Do NOT use

if ((k > 0) and (k <= 85)) k = 2 ok if ((k > 85) and (k <= 92)) k = 3 ok if (k > 92) k = 4 ok

TempX = ( a[k] * xf ) + ( b[k] * yf ) + e[k] TempY = ( c[k] * xf ) + ( d[k] * yf ) + f[k]

xf = TempX yf = TempY

if( (Count >= MaxIterations) or (Count != 0) ) xPoint = (floor(xf * MaxY / 11) + floor(MaxX / 2)) yPoint = (floor(yf * -MaxY / 11) + MaxY ) drawpoint( xPoint , yPoint ) ok

Count++ end

###----------------------------------------------------

endpaint() }

label1 { setpicture(p1) show() } return

</lang>


Run BASIC

<lang runbasic>maxpoints = 20000 graphic #g, 200, 200

  1. g fill("blue")

FOR n = 1 TO maxpoints p = RND(0)*100 IF p <= 1 THEN nx = 0 ny = 0.16 * y else if p <= 8 THEN nx = 0.2 * x - 0.26 * y ny = 0.23 * x + 0.22 * y + 1.6 else if p <= 15 THEN nx = -0.15 * x + 0.28 * y ny = 0.26 * x + 0.24 * y + 0.44 else nx = 0.85 * x +0.04 * y ny = -0.04 * x +0.85 * y + 1.6 end if x = nx y = ny

  1. g "color green ; set "; x * 17 + 100; " "; y * 17

NEXT n render #g

  1. g "flush"</lang>

Sidef

<lang ruby>require('Imager')

var w = 640 var h = 640

var img = %s<Imager>.new(xsize => w, ysize => h, channels => 3) var green = %s<Imager::Color>.new('#00FF00')

var (x, y) = (0, 0)

for r in (^1e5 -> lazy.map { 100.rand }) {

 (x, y) = (
   if    (r <=  1) { ( 0.00*x - 0.00*y,  0.00*x + 0.16*y + 0.00) }
   elsif (r <=  8) { ( 0.20*x - 0.26*y,  0.23*x + 0.22*y + 1.60) }
   elsif (r <= 15) { (-0.15*x + 0.28*y,  0.26*x + 0.24*y + 0.44) }
   else            { ( 0.85*x + 0.04*y, -0.04*x + 0.85*y + 1.60) }
 )
 img.setpixel(x => w/2 + 60*x, y => 60*y, color => green)

}

img.flip(dir => 'v') img.write(file => 'barnsleyFern.png')</lang>

zkl

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

Translation of: Java

<lang zkl>fcn barnsleyFern(){

  w,h:=640,640;
  bitmap:=PPM(w+1,h+1,0xFF|FF|FF);  // White background
  x,y, nx,ny:=0.0, 0.0, 0.0, 0.0;
  do(0d100_000){
     r:=(0).random(100);  // [0..100)%
     if     (r<= 1) nx,ny= 0, 		      0.16*y;
     else if(r<= 8) nx,ny= 0.2*x  - 0.26*y,  0.23*x + 0.22*y + 1.6;
     else if(r<=15) nx,ny=-0.15*x + 0.28*y,  0.26*x + 0.24*y + 0.44;
     else           nx,ny= 0.85*x + 0.04*y, -0.04*x + 0.85*y + 1.6;
     x,y=nx,ny;
     bitmap[w/2 + x*60, y*60] = 0x00|FF|00;  // Green dot
  }
  bitmap.writeJPGFile("barnsleyFern.jpg");

}();</lang>

ZX Spectrum Basic

Translation of: zkl

<lang zxbasic>10 REM Fractal Fern 20 PAPER 7: BORDER 7: BRIGHT 1: INK 4: CLS 30 LET maxpoints=20000: LET x=0: LET y=0 40 FOR n=1 TO maxpoints 50 LET p=RND*100 60 IF p<=1 THEN LET nx=0: LET ny=0.16*y: GO TO 100 70 IF p<=8 THEN LET nx=0.2*x-0.26*y: LET ny=0.23*x+0.22*y+1.6: GO TO 100 80 IF p<=15 THEN LET nx=-0.15*x+0.28*y: LET ny=0.26*x+0.24*y+0.44: GO TO 100 90 LET nx=0.85*x+0.04*y: LET ny=-0.04*x+0.85*y+1.6 100 LET x=nx: LET y=ny 110 PLOT x*17+127,y*17 120 NEXT n </lang> It is recommended to run on an emulator that supports running at full speed.