http://qs321.pair.com?node_id=1231457

in reply to circular area in a coordinates grid (AoA)

Try this (some slight changes to see a better circle)

```#!/usr/bin/perl

use strict;
use warnings;
use List::Util qw( max min );

my \$max = 40;

my @aoa = map { [ ( 'o' ) x (\$max + 1) ] } 0..\$max  ;

display( @aoa );

# @to_change will contain [y1,x1],[y2,x2]...
#my @to_change = illuminate( 5, 4, 6 );
my @to_change = illuminate( \$max >> 1, \$max >> 1, \$max - 2 >> 1 );

print "\n";
\$aoa[\$_->][\$_->] = 'x' for @to_change;
display( @aoa );

sub illuminate
{
my @to_change;
my \$center_r = shift;
my \$center_c = shift;
#...
for my \$row ( 0 .. \$#aoa )
{
my \$delta_x = eval { int sqrt \$radius ** 2 - (\$center_r - \$row) **
+ 2 };
if( defined \$delta_x )
{
my \$low = max 0, \$center_c - \$delta_x;
my \$high = min \$#{ \$aoa[\$row] }, \$center_c + \$delta_x;
push @to_change, map [ \$row, \$_ ], \$low .. \$high;
}
}
return @to_change;
}

sub display
{
foreach my \$row ( @_ )
{
foreach my \$col ( @\$row )
{
print \$col;
}
print "\n"
}
}

Replies are listed 'Best First'.
Re^2: circular area in a coordinates grid (AoA) -- updated
by Discipulus (Abbot) on Mar 19, 2019 at 22:44 UTC
Fantastic!

I suppose i can optimize it using for my \$row ( \$center_r - \$radius .. \$center_r + \$radius ) instead of processing the whole AoA

I never seen >> before: seems a int( \$_ / 2) operator.. thanks for this too!

L*

update

I adapted to return a hash instead. I feel happy with it. Thanks again

```#!/usr/bin/perl
use strict;
use warnings;
use List::Util qw( max min );

my \$max = 19;                                       #from OP
my @aoa = map { [ ( 'o' ) x (\$max + 1) ] } 0..\$max; #from OP

my %illu = illuminate( 0,0,12 );
display(@aoa);

%illu = illuminate( 0,10,4 );
display(@aoa);

%illu = illuminate( 10,10,6 );
display(@aoa);

%illu = illuminate( 10,0,5.5 );
display(@aoa);

sub illuminate{
my \$center_r = shift;
my \$center_c = shift;
my %ret;

foreach my \$row ( \$center_r - \$radius .. \$center_r + \$radius ){
my \$delta_x = \$radius ** 2 - (\$center_r - \$row) ** 2;
if( \$delta_x >= 0 ){

\$delta_x = int sqrt \$delta_x;
my \$low = max 0, \$center_c - \$delta_x;
my \$high = min \$#{ \$aoa[\$row] }, \$center_c + \$delta_x;
map { \$ret{ \$row.'_'.\$_ }++ } \$low .. \$high;
}
}
return %ret;
}

sub display{
print "\n";
foreach my \$row ( 0..\$#aoa ){
foreach my \$col ( 0..\$#{\$aoa[\$row]} ){
print  \$illu{\$row.'_'.\$col} ? ' ' : \$aoa[\$row][\$col] ;
+
}
print "\n"
}
}

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re^2: circular area in a coordinates grid (AoA)
by bliako (Prior) on Mar 19, 2019 at 23:34 UTC

Cool! But that eval poked my eye.

The following can potentially save on some sqrt's too:

```    my \$delta_x = \$radius ** 2 - (\$center_r - \$row) ** 2;
if( \$delta_x >= 0 ){
\$delta_x = int sqrt \$delta_x;
...

bw, bliako

you can also get rid of both squares

x˛ = r˛-y˛

now increment y2=y+1

x2˛ = r˛-(y+1)˛

x2˛ = r˛-y˛ - 2y - 1

x2˛ = x˛ - 2y -1

I'm too tired to get rid of the sqrt too now :)

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Just having some fun :)

Nothing wrong with having a little fun in a "proof-of-concept" example, is there?
It's not like it's production code :)

sorry maybe my comment sounded a bit aggresive (but it wasn't meant to be).