Draw a sphere: Difference between revisions

→‎Pure Perl 6: modernize a bit, add concurrency
(→‎Pure Perl 6: modernize a bit, add concurrency)
Line 2,846:
 
The C code is modified to output a .pgm file.
{{works with|Rakudo|20152018.0910}}
 
[[File:Sphere-perl6.png|thumb]]
<lang perl6>my $xwidth = my $yheight = 255; # must be odd
$x +|= 1; # must be odd
 
my @light = normalize([ 3, 2, -5 ]);
Line 2,856 ⟶ 2,855:
my $depth = 255;
 
sub MAIN ($outfile = 'sphere-perl6.pgm') {
spurt $outfile, "P5\n$xwidth $yheight\n$depth\n"; # .pgm header
my $out = open( $outfile, :a, :bin ) or die "$!\n";
$out.write( Blob.new(draw_sphere( ($xwidth-1)/2, .9, .2) ) );
$out.close;
}
 
sub normalize (@vec) { return @vec »/» ([+] @vec »*« @vec).sqrt }
 
sub dot (@x, @y) { return -([+] @x »*« @y) max 0 }
 
sub draw_sphere ( $rad, $k, $ambient ) {
my @pixels[$height];
my $r2 = $rad * $rad;
my @range = -$rad .. $rad;
for flat @range X @range.hyper.map: -> $x, $y {
my @row[$width];
if (my $x2 = $x * $x) + (my $y2 = $y * $y) < $r2 {
@range.map: -> $y {
my @vector = normalize([$x, $y, ($r2 - $x2 - $y2).sqrt]);
if (my $x2 = my$x * $intensityx) =+ dot(@light,my @vector)$y2 = $y ** $ky) +< $ambient;r2 {
my $pixel@vector = normalize(0[$x, max$y, ($intensityr2 *- $depth).Int)x2 min- $depthy2).sqrt]);
my $intensity = dot(@light, @vector) ** $k + $ambient;
@pixels.push($pixel);
my $pixel = (0 max ($intensity * $depth).Int) min $depth;
}
else { @row[$y+$rad] = $pixel;
@pixels.push(0);}
}else {
@row[$y+$rad] = 0;
}
}
@pixels[$x+$rad] = @row;
}
returnflat |@pixels.map: *.list;
}</lang>
 
10,333

edits