Greetings, all.
I was playing around with Image2D::pnpoly and Image2D::polyfill (and
polyfillv), and I noticed that the latter two do not have the same behavior
as pnpoly. I have some tests below.
use strict;
use warnings;
use PDL;
use PDL::Image2D;
# A triangle
my $px = pdl(3,15,9);
my $py = pdl(3,3,9);
print "Testing the triangle\n";
&testPoly($px,$py);
# A square (be careful to draw it convexly!)
$px = pdl(4,4,8,8);
$py = pdl(4,8,8,4);
print "Testing the square\n";
&testPoly($px,$py);
sub testPoly
{
my $px = shift;
my $py = shift;
my $points = $px->cat($py)->xchg(0,1);
my $img1 = zeroes(20, 11);
my $img2 = zeroes(20, 11);
my $img3 = zeroes(20, 11);
my $img4 = zeroes(20, 11);
my $img5 = pnpoly($img1->xvals,$img1->yvals,$px,$py);
print $img5, $img5->sumover, "\n";
$img2->polyfillv($points) .= 1;
print $img2, $img2->sumover, "\n";
$img3->polyfill($points, 1);
print $img3, $img3->sumover, "\n";
}
>From the output, I believe that pnpoly produces the correct answer insofar
as it produces the correct area for the square. Moreover, the documentation
for polyfill and polyfillv states that "fill the area *inside* the given
polygon with a given colour" and "return the (dataflown) area of an image *
within* a polygon," respectively. However, the area selected for color
filling in polyfill contains more than the points interior to the polygon,
and similarly for polyfillv.
After some investigation into PDL/Lib/Image2D, I found that polyfillv uses
polyfill, so their identical behavior is expected.
My proposed fix is to use pnpoly to determine the interior points. Then
polyfill becomes simply
sub PDL::polyfill
{
my ($im, $ps, $col) = @_;
barf("ps must contain pairwise points.\n") unless $ps->getdim(0) == 2;
barf("color not specified.\n") unless $col;
$im->where($im->pnpoly($im->xvals, $im->yvals, $ps->slice('0,:'),
$ps->slice('1,:'))) .= $col;
}
and polyfillv becomes
sub PDL::polyfillv
{
my ($im, $ps) = @_;
barf("ps must contain pairwise points.\n") unless $ps->getdim(0) == 2;
return $im->where($im->pnpoly($im->xvals, $im->yvals,
$ps->slice('0,:'), $ps->slice('1,:')));
}
This will remove the need for the PP version of polyfill. Assuredly, these
fixes are not optimal. If $im is large, then two large intermediates
($im->xvals and $im->yvals) are created.
I did not file this as a bug report, I wanted to run it by everyone to see
if I was missing something. Additionally, I am not closely familiar with
the coding standards, so I would appreciate any tips on that, as well.
Many thanks.
- Tim
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl