#!/usr/bin/perl -w use strict; use vars qw($image_w $image_h $image_w_2 $image_h_2); use Benchmark; use Getopt::Long; use Tk; $| = 1; my $max; # ( $image_w, $image_h ) = ( 1920, 1200 ); # ( $image_w, $image_h ) = ( 1920, 1080 ); # ( $image_w, $image_h ) = ( 1680, 1050 ); # ( $image_w, $image_h ) = ( 1600, 1200 ); # ( $image_w, $image_h ) = ( 1440, 900 ); # ( $image_w, $image_h ) = ( 1366, 768 ); # ( $image_w, $image_h ) = ( 1280, 1024 ); # ( $image_w, $image_h ) = ( 1280 800 ); # ( $image_w, $image_h ) = ( 1280, 720 ); # ( $image_w, $image_h ) = ( 1024, 768 ); # ( $image_w, $image_h ) = ( 800, 600 ); # ( $image_w, $image_h ) = ( 640, 480 ); # ( $image_w, $image_h ) = ( 640, 350 ); # ( $image_w, $image_h ) = ( 640, 200 ); # ( $image_w, $image_h ) = ( 320, 200 ); ( $image_w, $image_h ) = ( 160, 200 ); if ( scalar( grep( /^-/, @ARGV ) ) ) { GetOptions( 'width:i' => \$image_w, 'height:i' => \$image_h, 'help' => \&help, ); $image_w_2 = $image_w / 2; $image_h_2 = $image_h / 2; $max = ( ( $image_h < $image_w ? $image_h : $image_w ) - 10 ) **2; print qq{Creating $image_w x $image_h image, up to $max points\n}; } else { &help; } my %spinner_data = ( characters => [ q{|}, q{/}, q{-}, q{\\} ], bigscale => 100_000_000, scale => 10, count => 0, ); my $mw; my $f; my $can; my $img; my $rs; $mw = MainWindow->new; # Create outer containers $f = $mw->Frame->pack( -side => q{top}, -fill => q{both}, -expand => 1 ); $can = $mw->Canvas( -width => 320, -height => 240 )->pack(); # Create top frame container $rs = $f->Frame->pack( -side => q{left}, -fill => q{both}, -expand => 1 ); $f->Button( -text => q{Exit}, -command => sub { exit; } ) ->pack( -side => q{right}, -fill => q{both}, -expand => 1 ); # Reconfigure canvas size, and create image $can->configure( -width => $image_w, -height => $image_h ); $img = $mw->Photo( -width => $image_w, -height => $image_h, -palette => q{256/256/256} ); $img->blank(); $can->createImage( 0, 0, -image => $img, -anchor => q{nw} ); # Draw grid lines for image { foreach my $x ( 0 .. $image_w ) { $img->put( q{GREEN}, -to => ( $x, $image_h_2 ) ); } foreach my $y ( 0 .. $image_h ) { $img->put( q{GREEN}, -to => ( $image_w_2, $y ) ); } } # Generate pixels on image my @grid; my $time_took = timeit( 1, sub { get_grid( \$img, $max, \@grid ); } ); print qq{Generation took: }, timestr($time_took), qq{\n}; MainLoop; # # Subroutines # sub get_grid { my ( $img, $max, $found ) = @_; foreach my $g ( 0 .. $image_h ) { foreach my $i ( 0 .. $image_w ) { push @{ $found->[$g] }, 0; } } my $level = 0; my @numbers = get_primes_2($max); my $count = 0; my %d = ( x => 0, y => 0 ); my %p = ( x => 0, y => 0 ); foreach my $i ( 0 .. $#numbers ) { foreach my $s (qw(x y)) { $p{$s} += $d{$s}; } $count++; &spinner; if ( ( $level == 0 ) or ( ( $count == $level ) or ( $count == 2 * $level ) ) ) { if ( $count >= 2 * $level ) { $count = 0; $level++; } my $delta = 1; $delta *= -1 if ( $level % 2 ); %d = ( x => 0, y => 0 ); $d{x} -= $delta unless ($count); $d{y} += $delta if ($count); } ${$img}->put( q{BLUE}, -to => ( $image_w_2 + $p{x}, $image_h_2 + $p{y} ) ) if ( $numbers[$i] ); } } sub get_primes_2 { my ($max) = @_; my @found = ( 1 .. $max ); my $i = 0; $found[0] = 0; while ( $i <= int( sqrt($max) ) ) { $i++; next unless ( $found[$i] ); my $j = $found[$i]; my $k = $i + $j; while ( $k <= $#found ) { $found[$k] = 0; $k += $j; } } return @found; } sub help { printf <