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.
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.
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.
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.
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.
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
|
---|
Replies are listed 'Best First'. | |
---|---|
Nicely done
by Dragonfly (Priest) on Sep 23, 2003 at 20:59 UTC | |
by tsee (Curate) on Oct 05, 2003 at 23:18 UTC |