Subject: | polygons don't fit |
Date: | Wed, 28 Sep 2011 15:52:23 +0200 |
To: | <bug-Imager [...] rt.cpan.org> |
From: | "Neubauer, Ralf" <Ralf.Neubauer [...] wido.bv.aok.de> |
Hi.
Distribution name and version: Imager-0.85
Perl version: v5.12.4 -- Binary build 1205 [294981] provided by
ActiveState
Operating System vendor and version: WinXP
After building the very useful Imager module myself (because the
ActiveState PPMs are buggy and e.g. don't support PNG and JPEG) I still
get an effect that I first discovered some years ago with older
(ActiveState and trouchelle distributed) Versions of Imager and perl:
#! /usr/bin/perl
use warnings;
use strict;
use Imager;
my $img = new Imager(xsize => 100, ysize => 100, channels => 1);
my $white = Imager::Color->new(255, 255, 255);
my $black = Imager::Color->new(0, 0, 0);
$img->box(color => $white, filled => 1,
xmin => 0, ymin => 0, xmax => 99, ymax => 99);
$img->polygon(color => $black, points => [[0,0], [0,99], [99,99]]);
$img->polygon(color => $black, points => [[0,0], [99,99], [99,0]]);
$img->write(file => 'polygonmatch.bmp')
There is a fine grey line from (0,0) to (99,99). If I draw a shaded
triangulation, e.g. 3D shaded boxes, I don't get a nice shaded image,
but there are these lines between the triangles. Example:
use Imager::Fountain;
use Imager::Fill;
my $cells = 10;
my $xcell = 100;
my $ycell = 150;
$img = new Imager(xsize => $xcell*$cells, ysize => $ycell*$cells,
channels => 3);
my @color = map Imager::Color->new(map int rand 256, 0..2), 0..2;
my $fountain = Imager::Fountain->simple
(positions => [0, 0.1, 0.3, 0.7, 0.9, 1.0],
colors => [@color[0, 1, 2, 2, 3, 0]]);
for my $x (0..99) {
for my $y (0..99) {
my $tl = [$xcell*$x, $ycell*$y];
my $tr = [$xcell*$x+$xcell-1, $ycell*$y];
my $bl = [$xcell*$x, $ycell*$y+$ycell-1];
my $br = [$xcell*$x+$xcell-1, $ycell*$y+$ycell-1];
my $center = [$xcell*$x+int(($xcell-1)/2),
$ycell*$y+int(($ycell-1)/2)];
my $fill_top_bottom =
Imager::Fill->new(fountain => 'linear',
segments => $fountain,
xa => $tl->[0], ya => $tl->[1],
xb => $bl->[0], yb => $bl->[1],
);
my $fill_left_right =
Imager::Fill->new(fountain => 'linear',
segments => $fountain,
xa => $tl->[0], ya => $tl->[1],
xb => $tr->[0], yb => $tr->[1],
);
$img->polygon(fill => $fill_top_bottom, points => [$br, $center,
$bl]);
$img->polygon(fill => $fill_top_bottom, points => [$tl, $center,
$tr]);
$img->polygon(fill => $fill_left_right, points => [$bl, $center,
$tl]);
$img->polygon(fill => $fill_left_right, points => [$tr, $center,
$br]);
}
}
$img->write(file => 'polygonmatch2.bmp');
The easiest fix would be an option for non-antialiased polygons.
I tried hiding the artefacts behind lines:
for my $xincr (-1,0,1) {
$img->line(color => $color, aa => 0,
x1 => $bl->[0]+$xincr, y1 => $bl->[1],
x2 => $tr->[0]+$xincr, y2 => $tr->[1]);
$img->line(color => $color, aa => 0,
x1 => $br->[0]+$xincr, y1 => $br->[1],
x2 => $tl->[0]+$xincr, y2 => $tl->[1]);
}
but that doesn't catch all pixels -- and is still the wrong color
anyways.
Ralf