#!/usr/bin/perl -w use strict; # A simple CGI which runs a random set of points through the module # and displays the resulting polygons using the tag supported # by recent versions of Firefox and Safari. You can run it as a CGI # or from the command line like: # # perl ./voronoi.cgi > foo.html use Math::Geometry::Voronoi; use HTML::Template; use CGI qw/header/; my $text = do { local $/; }; my $template = HTML::Template->new(scalarref => \$text, die_on_bad_params => 0, loop_context_vars => 1); my $cgi = CGI->new(); my $n = $cgi->param('n') || 1000; $template->param(n => $n); die "What are you trying to do to me?" if $n > 5000; my $xsize = $cgi->param('xsize') || 1000; $template->param(xsize => $xsize); my $ysize = $cgi->param('ysize') || 500; $template->param(ysize => $ysize); my @points = map { [int(rand($xsize)), int(rand($ysize))] } (0 .. $n - 1); my %seen; @points = grep { not $seen{$_->[0], $_->[1]}++ } @points; my $geo = Math::Geometry::Voronoi->new(points => \@points); $geo->compute; my @polygons = $geo->polygons(normalize_vertices => sub { int($_[0]) }); my @poly; foreach my $poly ($geo->polygons) { my ($p, @verts) = @$poly; next if grep { $_->[0] > $xsize + 100 } @verts; next if grep { $_->[1] > $ysize + 100 } @verts; next if grep { $_->[0] < -100 } @verts; next if grep { $_->[1] < -100 } @verts; push @poly, { points => [ map { {x => int($_->[0]), y => int($_->[1])} } (@verts, $verts[0]) ], color => rand_color()}; } $template->param(polygons => \@poly); print header(), $template->output; sub rand_color { return join(',', map int(rand(255)), (1 .. 3)); } __DATA__ Math::Geometry::Voronoi Demo

Math::Geometry::Voronoi Demo

This is a demo of the Math::Geometry::Voronoi Perl module. To learn more, read the fine manual.

The image below shows a diagram containing random points. Only the complete polygons returned from the polygons() method are shown, which is why nothing is drawn around the edges. If you don't see anything please try again with Firefox - your browser may not support the new HTML <canvas> tag.