#!/usr/bin/perl use strict; # https://rosettacode.org/wiki/Polyspiral use warnings; use Tk; use List::Util qw( min ); my $size = 500; my ($width, $height, $x, $y, $dist); my $angleinc = 0; my $active = 0; my $wait = 1000 / 30; my $radian = 90 / atan2 1, 0; my $mw = MainWindow->new; $mw->title( 'Polyspiral' ); my $c = $mw->Canvas( -width => $size, -height => $size, -relief => 'raised', -borderwidth => 2, )->pack(-fill => 'both', -expand => 1); $mw->bind('' => sub { $width = $c->width; $height = $c->height; $dist = min($width, $height) ** 2 / 4 } ); $mw->Button(-text => $_->[0], -command => $_->[1], )->pack(-side => 'right') for [ Exit => sub {$mw->destroy} ], [ 'Start / Pause' => sub { $active ^= 1; step() } ]; MainLoop; -M $0 < 0 and exec $0; sub step { $active or return; my @pts = ($x = $width >> 1, $y = $height >> 1); my $length = 5; my $angle = $angleinc; $angleinc += 0.05 / $radian; while( ($x - $width / 2)**2 + ($y - $height / 2)**2 < $dist && @pts < 300 ) { push @pts, $x, $y; $x += $length * cos($angle); $y += $length * sin($angle); $length += 3; $angle += $angleinc; } $c->delete('all'); $c->createLine( @pts ); $mw->after($wait => \&step); }