#!perl
use
5.22.0;
XX
=> 0,
YY
=> 1,
};
XX
=> 0,
YY
=> 1,
};
sub
line {
my
(
$x
,
$y
) = @{
$_
[0] };
my
$dx
=
abs
(
$_
[1][XX] -
$x
);
my
$sx
=
$x
<
$_
[1][XX] ? 1 : -1;
my
$dy
=
abs
(
$_
[1][YY] -
$y
);
my
$sy
=
$y
<
$_
[1][YY] ? 1 : -1;
my
$err
= (
$dx
>
$dy
?
$dx
: -
$dy
) / 2;
my
@points
;
while
(1) {
push
@points
, [
$x
,
$y
];
last
if
$x
==
$_
[1][XX] and
$y
==
$_
[1][YY];
my
$e2
=
$err
;
if
(
$e2
> -
$dx
) {
$err
-=
$dy
;
$x
+=
$sx
;
}
if
(
$e2
<
$dy
) {
$err
+=
$dx
;
$y
+=
$sy
;
}
}
return
\
@points
;
}
}
sub
ppline {
my
(
$x
,
$y
) = @{
$_
[0] };
my
$dx
=
$_
[1][XX] -
$x
;
my
$dy
=
$_
[1][YY] -
$y
;
my
$distance
=
abs
(
$dx
);
my
$m
=
abs
(
$dy
);
$distance
=
$m
if
$m
>
$distance
;
return
[
$x
,
$y
]
if
$distance
== 0;
my
@points
;
my
$divn
= 1.0 /
$distance
;
my
$xstep
=
$dx
*
$divn
;
my
$ystep
=
$dy
*
$divn
;
my
$step
= 0;
while
(
$step
<=
$distance
) {
push
@points
, [ lround(
$x
), lround(
$y
) ];
$step
++;
$x
+=
$xstep
;
$y
+=
$ystep
;
}
return
\
@points
;
}
sub
points_of {
join
' '
,
map
{
"$_->[0],$_->[1]"
} @{
$_
[0] };
}
my
$first
= [ 0, 0 ];
my
$last
= [ 2, 11 ];
say
"Bc "
, points_of( bline(
$first
,
$last
) );
say
"Bp "
, points_of( Bresenham::line(
$first
,
$last
) );
say
"Lc "
, points_of( line(
$first
,
$last
) );
say
"Lp "
, points_of( ppline(
$first
,
$last
) );
cmpthese(
-10,
{
bres_c
=>
sub
{ bline(
$first
,
$last
) },
bres_pp
=>
sub
{ Bresenham::line(
$first
,
$last
) },
lerp_c
=>
sub
{ line(
$first
,
$last
) },
lerp_pp
=>
sub
{ ppline(
$first
,
$last
) },
}
);