Sierpinski square curve

From Rosetta Code
Revision as of 21:15, 1 March 2020 by Thundergnat (talk | contribs) (Start as a draft)
Sierpinski square curve 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.


Task

Produce a graphical or ASCII-art representation of a Sierpinski square curve of at least order 3.


Perl 6

Works with: Rakudo version 2020.02

<lang perl6>use SVG;

role Lindenmayer {

   has %.rules;
   method succ {
       self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
   }

}

my $sierpinski = 'X' but Lindenmayer( { X => 'XF-F+F-XF+F+XF-F+F-X' } );

$sierpinski++ xx 5;

my $dim = 600; my $scale = 6;

my @points = (-80, 298);

for $sierpinski.comb {

   state ($x, $y) = @points[0,1];
   state $d = $scale + 0i;
   when 'F' { @points.append: ($x += $d.re).round(1), ($y += $d.im).round(1) }
   when /< + - >/ { $d *= "{$_}1i" }
   default { }

}

my @t = @points.tail(2).clone;

my $out = './sierpinski-square-curve-perl6.svg'.IO;

$out.spurt: SVG.serialize(

   svg => [
       :width($dim), :height($dim),
       :rect[:width<100%>, :height<100%>, :fill<black>],
       :polyline[
         :points((@points, map {(@t »+=» $_).clone}, ($scale,0), (0,$scale), (-$scale,0)).join: ','),
         :fill<black>, :transform("rotate(45, 300, 300)"), :style<stroke:#61D4FF>,
       ],
       :polyline[
         :points(@points.map( -> $x,$y { $x, $dim - $y + 1 }).join: ','),
         :fill<black>, :transform("rotate(45, 300, 300)"), :style<stroke:#61D4FF>,
       ],
   ],

);</lang> See: Sierpinski-square-curve-perl6.svg (offsite SVG image)