MARKWIN has asked for the wisdom of the Perl Monks concerning the following question:

I've used Gd quite a bit and have recently come accross a what seems to be a bug. I can provide a more formal description with code samples and png output (rather long and tedious) but in essence the bug is this. When drawing arcs, it seems that the start and finish angles are rounded to the nearest degree. This means my arcs do not join up properly!!!

I'm using Gd version 2.30, windows 98 SE, Perl 5.8.0.

Have any other Monks come accross this ? Code examples below:

Zentara, that is a good idea. And for that reason I will post the code examples that I developed to demostrate this. I'd also like to hear from anyone who has had success writing sub-degree arcs with Gd, particulary windows 98 systems.

Here is my code, first one shows what should happen (roughly) when there is no bug. It draws some small arcs, but they are big enough not to be noticible:

use GD; my $size=500; my $scale=20; my $yinvert=-1; my ($xcenter,$ycenter)=(19.5,-5); my $i = new GD::Image($size,$size); $white = $i->colorAllocate(255,255,255); $black = $i->colorAllocate(0,0,0); $blue = $i->colorAllocate(0,0,255); $dred = $i->colorAllocate(128,0,0); $bred = $i->colorAllocate(255,0,0); $green = $i->colorAllocate(0,255,0); sub scaled # scale distances { my (@xyus)=@_; # unscaled xy pairs or distances. my @xys; # scaled xy pairs while (@xyus) { my $x=$xyus[0]; push(@xys, $x*$size/$scale); shift(@xyus); } return (@xys); } sub scale { my (@xyus)=@_; # unscaled xy pairs or distances. my @xys; # scaled xy pairs while (@xyus) { my $x=$xyus[0]-$xcenter; my $y=$xyus[1]-$ycenter*$yinvert; push(@xys, $x*$size/$scale+$size/2,$y*$size/$scale*$yinvert+$s +ize/2); shift(@xyus); shift(@xyus); } return (@xys); } # first draw some radial lines at 0.25 degree intervals. # the lines are 1 unit long and centered at the point 20,0. my $pi=4.0 * atan2(1, 1); my $rad=$pi/180.0; # to radions convert factor my $deg=180.0/$pi; # to degrees convert factor. my $v1=19; # vector lengths of lines being drawn from v1 to v2. my $v2=21; my $astep=10; my $oldangle; for my $j (0..4) { my $angle=$astep*$j; my $startx=$v1*cos($angle*$rad); my $starty=$v1*sin($angle*$rad); my $endx=$v2*cos($angle*$rad); my $endy=$v2*sin($angle*$rad); $i->line(scale($startx,$starty,$endx,$endy),$blue); # radial lines # now we draw some arcs, always 1 degree long, but starting at steps + of 0.1 degree # we draw the lowest arc nearest the center, ie 1 to 2 deg, then 1.1 + to 2.1 deg further out and so on. # angles are clockwise, and our +ve direction is acw, so in fact we +start at # 359 to 360, then further out 359.1 to 360.1, and so on for my $k (0..10) { my $kstep=1; my $kmove=0.2; $i->arc(scale(0,0),scaled(2*$v1+$k*$kmove,2*$v1+$k*$kmove),360-$a +ngle-$k*$kstep,360-$oldangle-$k*$kstep,$bred) if ($j%8==1); } $oldangle=$angle; } my $file="gdbug1.png"; open(F,">".$file) or die "Cannot open file ".$file; binmode F; print F $i->png; close F;
Here is very similar code that shows the bug:
use GD; my $size=500; my $scale=4.5; my $yinvert=-1; my ($xcenter,$ycenter)=(19.5,-1.5); my $i = new GD::Image($size,$size); $white = $i->colorAllocate(255,255,255); $black = $i->colorAllocate(0,0,0); $blue = $i->colorAllocate(0,0,255); $dred = $i->colorAllocate(128,0,0); $bred = $i->colorAllocate(255,0,0); $green = $i->colorAllocate(0,255,0); sub scaled # scale distances { my (@xyus)=@_; # unscaled xy pairs or distances. my @xys; # scaled xy pairs while (@xyus) { my $x=$xyus[0]; push(@xys, $x*$size/$scale); shift(@xyus); } return (@xys); } sub scale { my (@xyus)=@_; # unscaled xy pairs or distances. my @xys; # scaled xy pairs while (@xyus) { my $x=$xyus[0]-$xcenter; my $y=$xyus[1]-$ycenter*$yinvert; push(@xys, $x*$size/$scale+$size/2,$y*$size/$scale*$yinvert+$s +ize/2); shift(@xyus); shift(@xyus); } return (@xys); } # first draw some radial lines at 0.25 degree intervals. # the lines are 1 unit long and centered at the point 20,0. my $pi=4.0 * atan2(1, 1); my $rad=$pi/180.0; # to radions convert factor my $deg=180.0/$pi; # to degrees convert factor. my $v1=19; # vector lengths of lines being drawn from v1 to v2. my $v2=20; my $astep=1; my $oldangle; for my $j (0..7) { my $angle=$astep*$j; my $startx=$v1*cos($angle*$rad); my $starty=$v1*sin($angle*$rad); my $endx=$v2*cos($angle*$rad); my $endy=$v2*sin($angle*$rad); $i->line(scale($startx,$starty,$endx,$endy),$blue); # radial lines # now we draw some arcs, always 1 degree long, but starting at steps + of 0.1 degree # we draw the lowest arc nearest the center, ie 1 to 2 deg, then 1.1 + to 2.1 deg further out and so on. # angles are clockwise, and our +ve direction is acw, so in fact we +start at # 359 to 360, then further out 359.1 to 360.1, and so on for my $k (0..20) { my $kstep=0.1; my $kmove=0.1; $i->arc(scale(0,0),scaled(2*$v1+$k*$kmove,2*$v1+$k*$kmove),360-$a +ngle-$k*$kstep,360-$oldangle-$k*$kstep,$bred) if ($j%8==1); } $oldangle=$angle; } my $file="gdbug2.png"; open(F,">".$file) or die "Cannot open file ".$file; binmode F; print F $i->png; close F;

The png file on a system with no bug will show a smoothly varying set of red arcs, that do not all start and stop on the blue radial lines. On a system with the bug, all red arcs start and stopco-incident with blue radial (straight) lines.

The first and second code samples generate these two png files on my system:

Ok, well nearly and clearly faulty
The second of these shows cleary the suspect behaviour.

Replies are listed 'Best First'.
Re: Possible Gd Bug?
by PodMaster (Abbot) on Nov 15, 2005 at 14:06 UTC
    It's not a bug, its a feature :) The gd Arc functions take integers

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      Hmm I see what you mean. Although it doesnt say so in the Perl Gd manual page. :-(

      Do you know any way round this or an alternative package you would recommend for line drawing that ia able to draw arcs acurately?

Re: Possible Gd Bug?
by zentara (Cardinal) on Nov 15, 2005 at 13:02 UTC
    More likely, it's a bug in Windows98, and the way it runs ActiveState. With most GD questions, it usually comes down to get the latest version. Maybe you should ask someone with WinXP to run your script and see if the results are the same.

    I'm not really a human, but I play one on earth. flash japh