Try this. I'm not certain it's exactly equivalent to your original as I had some trouble understanding your 'drawing' code, but it's not far off. Your use of %curpass confused me as it seems unnecessary.
You should be able to relate the sub genEndPoints() to the code at the end of the page I linked above. Rather than generating all the points on the circumference for all integer radii upto max radius, it generates only the endpoints (8 at a time using symmetry), of the raster lines required to 'fill' the circle and then draws those lines. Let me know if anything is unclear.
#!/usr/bin/perl
use strict;
use warnings;
use CGI ();
my $q = CGI->new;
# use CGI::Carp 'fatalsToBrowser';
my %circle;
my $prev_data;
# Read the previous circles
my @prev_circles;
{
my @x_vals = $q->param('x');
my @y_vals = $q->param('y');
my @r_vals = $q->param('r');
for(my $i = 0; $i < @r_vals; $i++) {
foreach ($r_vals[$i], $x_vals[$i], $y_vals[$i]) {
die "All values must be positive integers!\n" if /[^\d\.]/
}
push(@prev_circles, {
r => $r_vals[$i],
x => $x_vals[$i],
y => $y_vals[$i],
});
}
}
sub genEndPoints {
my( $radius, $xCenter, $yCenter ) = @_;
my %endPoints;
my( $x, $y, $p ) = ( 0, $radius, 1 - $radius );
$endPoints{ $yCenter } = [ $xCenter - $radius, $xCenter + $radius
+ ];
while( $x < $y ) {
$x++;
if( $p < 0 ) {
$p += 2 * $x + 1;
} else {
$y--;
$p += 2 * ( $x - $y + 1 );
}
$endPoints{ $yCenter - $y } = [ $xCenter - $x, $xCenter + $x
+];
$endPoints{ $yCenter + $y } = [ $xCenter - $x, $xCenter + $x
+];
$endPoints{ $yCenter - $x } = [ $xCenter - $y, $xCenter + $y
+];
$endPoints{ $yCenter + $x } = [ $xCenter - $y, $xCenter + $y
+];
}
return \%endPoints;
}
# 'Draw' the circle in the hash.
foreach my $circle (@prev_circles) {
my $rmax = $circle->{'r'};
my $center_x = $circle->{'x'};
my $center_y = $circle->{'y'};
$prev_data .= qq~
<input type="hidden" name="r" value="$rmax" />
<input type="hidden" name="x" value="$center_x" />
<input type="hidden" name="y" value="$center_y" />\n
~;
my $endPoints = genEndPoints( $rmax, $center_x, $center_y );
for my $y ( keys %{ $endPoints } ) {
my( $startX, $endX ) = @{ $endPoints->{ $y } };
for my $x ( $startX .. $endX ) {
$circle{ $y }{ $x }++;
}
}
}
my $output = q~<html>
<head>
<title>A circle as a table</title>
<style type="text/css">
body {background: #888;}
.c1 {background: #000;}
.c2 {background: #008;}
.c3 {background: #00f;}
.c4 {background: #08f;}
.c5 {background: #0ff;}
.c6 {background: #8ff;}
.c7 {background: #fff;}
</style>
</head>
<body>
<table>
~;
foreach my $rowid (0 .. max(keys %circle)) {
my $row = $circle{$rowid};
$output .= "<tr>";
foreach my $columnid (0 .. max(keys %{$row})) {
my $column = $row->{$columnid};
my $class = '';
$column = 7 if $column > 7;
$class = qq~ class="c$column"~ if $column;
$output .= qq~<td$class></td>~;
}
$output .= "</tr>\n";
}
$output .= qq~
</table>
<br />
<br />
<form method="post" >
$prev_data
<br />New circle's radius: <input type="text" size="10" name="r" value
+="20" />
<br />New circle's center: (<input type="text" size="10" name="x" valu
+e="50" />,
<input type="text" size="10" name="y" value="50" />)
<br /><input type="submit" />
</form>
</body>
</html>
~;
print $q->header, $output;
sub max {
my $max = 0;
foreach (@_) { $max = $_ if $_ > $max; }
return $max;
}
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.