#!/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 $/; <DATA> };
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__
<html>

Math::Geometry::Voronoi Demo

<body>

Math::Geometry::Voronoi Demo

This is a demo of
the Math::Geometry::Voronoi (http://search.cpan.org/~samtregar/Math-Geometry-Voronoi)
Perl module.  To learn
more, read
the fine manual (http://search.cpan.org/~samtregar/Math-Geometry-Voronoi/lib/Math/Geometry/Voronoi.pm).

The image below shows a diagram containing <tmpl_var n> 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.

<canvas style="border: 1px solid black" id="map" width="<tmpl_var xsize>" height="<tmpl_var ysize>">

