Xiaolin Wu's line algorithm: Difference between revisions

Content added Content deleted
(Updated D entry)
No edit summary
Line 575: Line 575:
End Function
End Function
</lang>
</lang>
=={{header|Perl}}==
This is mostly a translation of the pseudo-code on Wikipedia, except that the $plot trick was inspired by the perl6 RosettaCode example.
<lang perl>#!perl
use strict;
use warnings;

sub plot {
my ($x, $y, $c) = @_;
printf "plot %d %d %.1f\n", $x, $y, $c if $c;
}

sub ipart {
int shift;
}

sub round {
int( 0.5 + shift );
}

sub fpart {
my $x = shift;
$x - int $x;
}

sub rfpart {
1 - fpart(shift);
}
sub drawLine {
my ($x0, $y0, $x1, $y1) = @_;

my $plot = \&plot;

if( abs($y1 - $y0) > abs($x1 - $x0) ) {
$plot = sub { plot( @_[1, 0, 2] ) };
($x0, $y0, $x1, $y1) = ($y0, $x0, $y1, $x1);
}

if( $x0 > $x1 ) {
($x0, $x1, $y0, $y1) = ($x1, $x0, $y1, $y0);
}

my $dx = $x1 - $x0;
my $dy = $y1 - $y0;
my $gradient = $dy / $dx;

my @xends;
my $intery;

# handle the endpoints
for my $xy ([$x0, $y0], [$x1, $y1]) {
my ($x, $y) = @$xy;
my $xend = round($x);
my $yend = $y + $gradient * ($xend - $x);
my $xgap = rfpart($x + 0.5);

my $x_pixel = $xend;
my $y_pixel = ipart($yend);
push @xends, $x_pixel;

$plot->($x_pixel, $y_pixel , rfpart($yend) * $xgap);
$plot->($x_pixel, $y_pixel+1, fpart($yend) * $xgap);
next if defined $intery;
# first y-intersection for the main loop
$intery = $yend + $gradient;
}

# main loop

for my $x ( $xends[0] + 1 .. $xends[1] - 1 ) {
$plot->($x, ipart ($intery), rfpart($intery));
$plot->($x, ipart ($intery)+1, fpart($intery));
$intery += $gradient;
}
}

if( $0 eq __FILE__ ) {
drawLine( 0, 1, 10, 2 );
}
__END__
</lang>
{{out}}
<pre>plot 0 1 0.5
plot 10 2 0.5
plot 1 1 0.9
plot 1 2 0.1
plot 2 1 0.8
plot 2 2 0.2
plot 3 1 0.7
plot 3 2 0.3
plot 4 1 0.6
plot 4 2 0.4
plot 5 1 0.5
plot 5 2 0.5
plot 6 1 0.4
plot 6 2 0.6
plot 7 1 0.3
plot 7 2 0.7
plot 8 1 0.2
plot 8 2 0.8
plot 9 1 0.1
plot 9 2 0.9</pre>


=={{header|Perl 6}}==
=={{header|Perl 6}}==
{{works with|niecza|2013-03-02}}
{{works with|niecza|2013-03-02}}