boxer / lace-maker

use warnings;
use strict;
use Data::Dumper;
use Math::Geometry::Voronoi;
use Math::Clipper;
use Getopt::Long qw(:config no_ignore_case);

my $xsize = 100;
my $ysize = 100;
my $num = 32;
my $line_width = 2;

my $usage = <<__END_HELP__;
Usage: lace-maker [options] > lace.svg
    -h | -? | --help           This help
    -x N                       X dimension in mm
    -y N                       Y dimension in mm
    -n N                       Number of points
    -w N                       Line width in mm
Note that if the point density is too high the Voronoi generation might
fail, causing an empty SVG output.

	'h|?|help'		=> sub { print $usage; exit 0 },
	'x=f'			=> \$xsize,
	'y=f'			=> \$ysize,
	'n=i'			=> \$num,
	'w=f'			=> \$line_width,
) or die $usage;

my @points = map { [
	(rand $xsize*1.1) - $xsize*.05,
	(rand $ysize*1.1) - $ysize*.05,
] } 0..$num;

my $geo = Math::Geometry::Voronoi->new(points => \@points);

my @polys = $geo->polygons;

# Inset everything and then replace the polygons inplace
for my $poly (@polys)
	# Remove index value
	shift @$poly;

	# Inset the polygon by the line width (negative == towards center)
	my $n = Math::Clipper::offset([$poly], -$line_width);
	$poly = $n->[0];

# Clip it by the bounding box
my $bounding = [

my $clipper = Math::Clipper->new;
my $scale = Math::Clipper::integerize_coordinate_sets($bounding, @polys);

eval {
} or die "Bad polygons?  Try reducing number of points or line width.\n";


my $n = $clipper->execute(Math::Clipper::CT_INTERSECTION);
Math::Clipper::unscale_coordinate_sets($scale, $n);
@polys = @$n;

#print Dumper(\@polys);

print <<"";
<!-- Created with lace-maker ( -->
<svg xmlns="">
<g transform="scale(3.543307)"><!-- scale to mm -->

for my $poly (@polys)
	print <<"";
			stroke		= "#ff0000"
			fill		= "none"
			stroke-width	= "0.1px"
			d		= "M

	for my $pt (@$poly)
		my ($x,$y) = @$pt;
		print "$x,$y\n";

	# Close the path
	print <<"";

	#print Dumper($poly);

print <<"";

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.