This is a short introduction to one of the CPAN modules dealing with fractals. According to the Merriam-Webster dictionary, a fractal is

"any of various extremely irregular curves or shapes for which any suitably chosen part is similar in shape to a given larger or smaller part when magnified or reduced to the same size."

While that's pretty hard to parse for my head, I think I can safely assume that most readers have seen one of the more famous fractals like the von-Koch Curve before. Hence I will not go into details on fractals or even the underlying mathematics. I suggest you have a look at the documents in the references section below.

Introducing Math::Fractal::Curve

The Math::Fractal::Curve module from CPAN may be used to recursively calculate fractal curves from simple generator datastructures to arbitrary precisions. These generators specify a number of distances in two dimensions and relative to the distance from (0,0) to (1,0).

Math::Fractal::Curve calculates fractals by repeatedly replacing all distances in the fractal with a scaled and rotated version of the distances specified by the generator.

Getting the feet wet

Let's start writing some code that demonstrates basic usage.

use strict; use warnings; use Math::Fractal::Curve; # This generates a von Koch-curve. my $generator = [ [0, 0, 1/3, 0 ], [1/3, 0, 1/2, sqrt(5)/6], [1/2, sqrt(5)/6, 2/3, 0 ], [2/3, 0, 1, 0 ], ]; # New curve generator my $curve_gen = Math::Fractal::Curve->new(generator => $generator); # New curve my $curve = $curve_gen->line( start => [-2, 0], end => [2, 0], ); my $depth = 5; my $edges = $curve->fractal($depth);

As you can see in the above example, generators in their simplest form are syntactically no more than nested array references and a few numbers. The example specifies four distances (the four inner array references) that will be used to replace any distance. The numbers are relative to the length of the replaced distance and have the same orientation.

The next step taken is to create a new Math::Fractal::Curve object which we seed with a starting distance using the line() method. The last step required to generate a list of distances that represent a von-Koch Curve to the 5th recursion.

Great, so what? -or- Imager to the rescue

Now we have a large array of array refs that each hold four numbers. That did not take us much closer to the pretty picture I gave as an example above. We'll need some drawing to realize that. Luckily, Arnar Mar Hrafnkelsson wrote the excellent Imager module to do the hard work!

# append to the other part of the script use Imager; # Generate sensible filename for image. my $filename = sprintf('Koch-Depth%02i.png', $depth); # Image dimensions my $max_x = 1000; my $max_y = 400; my $img = Imager->new(xsize => $max_x, ysize => $max_y); my $color = Imager::Color->new( 0, 0, 255 ); # blue # Scale dimensions by 200. @$_ = map $_*200, @$_ foreach @$edges; foreach (@$edges) { $img->line( color => $color, x1 => $max_x / 2 + $_->[0], # start y1 => $max_y - 50 - $_->[1], x2 => $max_x / 2 + $_->[2], # end y2 => $max_y - 50 - $_->[3], ); } $img->write(file=>$filename) or die $img->errstr;

No deep thinking required to understand the above code. We scale the distances to be large enough to be drawn conveniently. The call to Imager's line() method may look more complicated than it really is. All the maths is just moving the fractal to the center of the image.

More'o'That

The above example demonstrates the bare minimum needed to get started with letting your computer plot some fractals, but it has a few limitations and does not demonstrate the full power of the module.
One problem that arises when recursing 8, 9, or even 10 times is the memory footprint of the program. All edges will be stored in memory and holding 4**10 array references scares the hell out of my gigabyte of RAM.
It isn't hard to do a depth-first search on the fractal tree while generating it using some of the other methods of the module. Such a routine has been used for generating this image.
Furthermore, Math::Fractal::Curve can create fractals that don't strictly qualify as such. This is possible by assigning an anonymous subroutine that returns a generator structure as the Math::Fractal::Curve object's generator.

References

MathWorld
Kenneth J. Falconer, "Fractal Geometry. Mathematical Foundations and Applications", (c) 1990 at Jon Wiley & Sons Ltd., Chichester
Math::Fractal::DLA
Math::Fractal::Mandelbrot
Math::Fractal::Curve


In reply to Plot Pretty Fractals with Perl by tsee

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.