2022 twenty-four merry days of Perl Feed
Merry Christmas and Happy New Year! :-)
Our holiday-themed programming goal is to implement a fun little Perl application, which will display a Christmas tree using the Sierpinski fractal algorithm.
Let's begin by reviewing the code for generating Sierpinski Triangle fractals, stored in a file named Sierpinski.pm.
If you are an experienced Perl programmer, you will immediately notice the definition and utilization of data types such as integer
and number
, as well as data structures such as integer::arrayref
and integer::arrayref::arrayref
etc. Data types and data structures, along with other Perl programming strategies such as CRITICS
as well as subroutine $RETURN_TYPE
and @ARG
named input arguments, are included for best practices and compatibility with the Perl compiler.
1: | # [[[ PREPROCESSOR ]]] |
Let's see what happens when we call the sierpinski()
subroutine, passing in only 1 level of recursion for simplicity...
The recursion directly populates $retval
in reverse order, from highest index to lowest index, eventually ending at index 0 with no further recursion to be done, and all the values are returned back to the original subroutine call. Because of this reverse-index population, the hard-coded initial triangle is stored at the highest (not the lowest) index in $retval
, as you can see in the Perl one-liner (two-liner?) below. The initial triangle's hard-coded definition is done during declaration for brevity, and the to-be-populated element is left as undef.
1: | $ perl -e 'use MathPerl::Fractal::Sierpinski; my $retval = [undef, [[512, 100], [212, 600], [812, 600]]]; |
First, sierpinski()
will display the 3 [ x, y ]
cartesian coordinates representing the 3 corners of our initial input triangle, received in the my number::arrayref::arrayref $triangle
argument:
1: | in sierpinski(), received $recursions_remaining = 1 |
Then the Sierpinski algorithm creates 3 sub-triangles and makes a recursive call to sierpinski()
for each sub-triangle:
1: | in sierpinski(), received $recursions_remaining = 0 |
If we were to render these 3 sub-triangles in white, it would look like a monochrome triforce:
After all recursion has completed, we are left with our final number::arrayref::arrayref::arrayref::arrayref
data structure, which contains all generated triangles grouped by recursion level:
1: | have $my_triangle_groups = |
Ultimately, it is the $my_triangle_groups
data which will be rendered to comprise the main triangular body of the Christmas tree.
Next let's review the Perl code for generating the Christmas Tree data and rendering the Simple DirectMedia Layer (SDL) graphics, stored in a file named ChristmasTree.pm:
1: | # [[[ HEADER ]]] |
The above Christmas tree code is pretty much the simplest 2-D graphics rendering system I could write using SDL, with the ability to be exited gracefully instead of having to type Ctrl-Z
and then $ killall -KILL perl
.
Last, we only need a few lines of driver code to run it all:
sierpinski_triangles_christmas.pl
1: | #!/usr/bin/env perl |
If you were to run the above program, which includes 5 colors for 5 levels of recursion, then you would see a rendered series of images similar to the following:
1: | $ ./sierpinski_triangles_christmas.pl |
However, before you can run this program you will need to install the SDL dependencies:
1: | $ cpanm -v SDL SDLx::App SDL::Event SDL::Events |
Also, the easiest way to run this Fractal Christmas Tree program is to copy or download the monolithic code below (instead of all 3 files above), and then paste it into a single executable Perl file:
sierpinski_triangles_christmas_monolith.pl
1: | #!/usr/bin/env perl |
If you review the graphics rendering code above, you will see the while(1)
main run loop which twinkles the Christmas tree lights, displaying an animated color change once every second.
Run it yourself and bask in the Perl yuletide glory of your very own Sierpinski triangle fractal Christmas tree!
1: | $ ./sierpinski_triangles_christmas_monolith.pl |
Merry Christmas to all, and to all a good night! :-)