Sunflower fractal

From Rosetta Code
Sunflower fractal 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.

Draw Sunflower fractal


Go

Library: Go Graphics
Translation of: Ring


The image produced, when viewed with (for example) EOG, is similar to the Ring entry. <lang go>package main

import (

   "github.com/fogleman/gg"
   "math"

)

func main() {

   dc := gg.NewContext(400, 400)
   dc.SetRGB(1, 1, 1)
   dc.Clear()
   dc.SetRGB(0, 0, 1)
   c := (math.Sqrt(5) + 1) / 2
   numberOfSeeds := 3000
   for i := 0; i <= numberOfSeeds; i++ {
       fi := float64(i)
       fn := float64(numberOfSeeds)
       r := math.Pow(fi, c) / fn
       angle := 2 * math.Pi * c * fi
       x := r*math.Sin(angle) + 200
       y := r*math.Cos(angle) + 200
       fi /= fn / 5
       dc.DrawCircle(x, y, fi)
   }
   dc.SetLineWidth(1)
   dc.Stroke()
   dc.SavePNG("sunflower_fractal.png")

}</lang>

JavaScript

HTML to test

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Vibrating rectangles</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            body{background-color:black;text-align:center;margin-top:150px}
        </style>
        <script src="sunflower.js"></script>
    </head>
    <body onload="start()">
        <div id='wnd'></div>
    </body>
</html>

<lang javascript> const SIZE = 400, HS = SIZE >> 1, WAIT = .005, SEEDS = 3000,

     TPI = Math.PI * 2, C = (Math.sqrt(10) + 1) / 2;

class Sunflower {

   constructor() {
       this.wait = WAIT;
       this.colorIndex = 0;
       this.dimension = 0;
       this.lastTime = 0;
       this.accumulator = 0;
       this.deltaTime = 1 / 60;
       this.colors = ["#ff0000", "#ff8000", "#ffff00", "#80ff00", "#00ff00", "#00ff80", 
                      "#00ffff", "#0080ff", "#0000ff", "#8000ff", "#ff00ff", "#ff0080"];
       this.canvas = document.createElement('canvas');
       this.canvas.width = SIZE;
       this.canvas.height = SIZE;
       const d = document.getElementById("wnd");
       d.appendChild(this.canvas);
       this.ctx = this.canvas.getContext('2d');
   }
   draw(clr, d) {
       let r = Math.pow(d, C) / SEEDS;
       let angle = TPI * C * d;
       let x = HS + r * Math.sin(angle), 
           y = HS + r * Math.cos(angle);
       this.ctx.strokeStyle = clr;
       this.ctx.beginPath();
       this.ctx.arc(x, y, d / (SEEDS / 50), 0, TPI);
       this.ctx.closePath();
       this.ctx.stroke();
   }
   update(dt) {
       if((this.wait -= dt) < 0) {
           this.draw(this.colors[this.colorIndex], this.dimension);
           this.wait = WAIT;
           if((this.dimension++) > 600) {
               this.dimension = 0;
               this.colorIndex = (this.colorIndex + 1) % this.colors.length;
           }
       }
   }
   start() {
       this.loop = (time) => {
           this.accumulator += (time - this.lastTime) / 1000;
           while(this.accumulator > this.deltaTime) {
               this.accumulator -= this.deltaTime;
               this.update(Math.min(this.deltaTime));
           }
           this.lastTime = time;
           requestAnimationFrame(this.loop);
       }
       this.loop(0);
   }

} function start() {

   const sunflower = new Sunflower();
   sunflower.start();

}

</lang>

Microsoft Small Basic

Translation of: Ring

<lang smallbasic>' Sunflower fractal - 24/07/2018

 GraphicsWindow.Width=410
 GraphicsWindow.Height=400
 c=(Math.SquareRoot(5)+1)/2
 numberofseeds=3000
 For i=0 To numberofseeds
   r=Math.Power(i,c)/numberofseeds
   angle=2*Math.Pi*c*i
   x=r*Math.Sin(angle)+200
   y=r*Math.Cos(angle)+200
   GraphicsWindow.DrawEllipse(x, y, i/numberofseeds*10, i/numberofseeds*10)
 EndFor </lang>
Output:

Sunflower fractal

Perl

Translation of: Sidef

<lang perl>use utf8; use constant π => 3.14159265; use constant φ => (1 + sqrt(5)) / 2;

my $scale = 600; my $seeds = 5*$scale;

print F qq{<svg xmlns="http://www.w3.org/2000/svg" width="$scale" height="$scale" style="stroke:gold">

          <rect width="100%" height="100%" fill="black" />\n};

for $i (1..$seeds) {

   $r = 2 * ($i**φ) / $seeds;
   $t = 2 * π * φ * $i;
   $x = $r * sin($t) + $scale/2;
   $y = $r * cos($t) + $scale/2;
   printf F qq{<circle cx="%.2f" cy="%.2f" r="%.1f" />\n}, $x, $y, sqrt($i)/13;

}

print F "</svg>\n";</lang>

Perl 6

Works with: Rakudo version 2018.06

This is not really a fractal. It is more accurately an example of a Fibonacci spiral or Phi-packing.

Or, to be completely accurate: It is a variation of a generative Fermat's spiral using the Vogel model to implement phi-packing. See: https://thatsmaths.com/2014/06/05/sunflowers-and-fibonacci-models-of-efficiency

<lang perl6>use SVG;

my $seeds = 3000; my @center = 300, 300; my $scale = 5;

constant \φ = (3 - 5.sqrt) / 2;

my @c = map {

   my ($x, $y) = ($scale * .sqrt) «*« |cis($_ * φ * τ).reals »+« @center;
   [ $x.round(.01), $y.round(.01), (.sqrt * $scale / 100).round(.1) ]

}, 1 .. $seeds;

say SVG.serialize(

   svg => [
       :600width, :600height, :style<stroke:yellow>,
       :rect[:width<100%>, :height<100%>, :fill<black>],
       |@c.map( { :circle[:cx(.[0]), :cy(.[1]), :r(.[2])] } ),
   ],

);</lang> See: Phi packing (SVG image)

Ring

<lang ring>

  1. Project : Sunflower fractal

load "guilib.ring"

paint = null

new qapp

       {
       win1 = new qwidget() {
                 setwindowtitle("Sunflower fractal")
                 setgeometry(100,100,320,500)
                 label1 = new qlabel(win1) {
                             setgeometry(10,10,400,400)
                             settext("")
                 }
                 new qpushbutton(win1) {
                         setgeometry(100,400,100,30)
                         settext("draw")
                         setclickevent("draw()")
                 }
                 show()
       }
       exec()
       }

func draw

       p1 = new qpicture()
              color = new qcolor() {
              setrgb(0,0,255,255)
       }
       pen = new qpen() {
                setcolor(color)
                setwidth(1)
       }
       paint = new qpainter() {
                 begin(p1)
                 setpen(pen)
       c = (sqrt(5) + 1) / 2
       numberofseeds = 3000
       for i = 0 to numberofseeds
             r = pow(i, c ) / (numberofseeds)
             angle = 2 * 3.14 * c * i
             x = r * sin(angle) + 100
             y = r * cos(angle) + 100
            drawellipse(x, y, i / (numberofseeds / 10), i / (numberofseeds / 10))
       next
       endpaint()
       }
       label1 { setpicture(p1) show() }

</lang> Output:

Sunflower fractal

Sidef

Translation of: Go

<lang ruby>require('Imager')

func draw_sunflower(seeds=3000) {

   var img = %O<Imager>.new(
       xsize => 400,
       ysize => 400,
   )
   var c = (sqrt(1.25) + 0.5)
   { |i|
       var r = (i**c / seeds)
       var θ = (2 * Num.pi * c * i)
       var x = (r * sin(θ) + 200)
       var y = (r * cos(θ) + 200)
       img.circle(x => x, y => y, r => i/(5*seeds))
   } * seeds
   return img

}

var img = draw_sunflower() img.write(file => "sunflower.png")</lang> Output image: Sunflower fractal

zkl

Translation of: Go

Uses Image Magick and the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl <lang zkl>fcn sunflower(seeds=3000){

  img,color := PPM(400,400), 0x00ff00;		// green
  c:=((5.0).sqrt() + 1)/2;
  foreach n in ([0.0 .. seeds]){  // floats
     r:=n.pow(c)/seeds;
     x,y := r.toRectangular(r.pi*c*n*2);
     r=(n/seeds*5).toInt();
     img.circle(200 + x, 200 + y, r,color);
  }
  img.writeJPGFile("sunflower.zkl.jpg");

}();</lang>

Output:

Image at sunflower fractal