Page 1 of 1

Question About a Simple Graph

Posted: Wed Feb 06, 2013 11:04 am
by eBob
I am new to PHP and even newer to graphics in PHP, and I don't know if what I am seeing I can fix or if I just have to live with it. In the simple graph, attached, 4 straight lines (radii) should be perfectly horizontal or vertical (2 of each). But line 4 is not. Is there anything I can do about that?

There are also four diagonal lines, in red. On my monitor two of those, 1 and 4, look very good, i.e. perfectly smooth. But 2 and 3 both have a one pixle dog leg at what appears to be the midpoint. Normally I wouldn't expect a diagonal line to be perfectly smooth. But since lines 1 and 3 should be parallel and since line 3 appears perfectly smooth why doesn't 1? And the same question of course regarding lines 2 and 4.

Code below. Any help will be appreciated. Thanks, Bob

Code: Select all

<?php

function imgmsg($im,$msg)
{
   static $msgoff = 0;
   $black = imagecolorallocate($im,0,0,0);
    $msgoff += 10;
//    imagestring($im,3,10,$msgoff,$msg,$black);
} 

//set up image
$height = 600;
$width = 600;
$im = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($im,255,255,255);
$black = imagecolorallocate($im,0,0,0);
$red = imagecolorallocate($im,255,0,0);

// create the image

imagefill($im,0,0,$white);

// draw the circle
$center_x = $width/2;
$center_y = $height/2;
imagearc($im,$center_x,$center_y,$width-4,$height-4,0,360,$black );

// draw the radii
$radius = ($width-4)/2;
imgmsg($im,'$radius is ' . $radius);
$degree_interval = 90;
//imagestring($im,3,10,10,'before loop',$black);
//for ($angle = $degree_interval; $angle <= 360; $angle += $degree_interval )
for ($angle = 0; $angle <= 359; $angle += $degree_interval )
{    imgmsg($im,'in loop');
    $x = sin(deg2rad($angle)) * $radius;
    imgmsg($im,'$angle is '.$angle.' / $x is '.$x . ' / sin is ' . sin(deg2rad($angle)) );
    $y = sin(deg2rad(90-$angle)) * $radius;
    imgmsg($im,'$angle is ' . (90-$angle) .' / $y is '.$y. ' / sin is ' . sin(deg2rad(90-$angle)));
    imageline($im,$center_x,$center_y,$x+$center_x, $y+$center_y,$black);

    $points_x[] = $x;
    $points_Y[] = $y;
    
    if (isset($last_x))
      { imageline($im,$last_x+$center_x,$last_y+$center_y,$x+$center_x,$y+$center_y,$red);
       }
       else {$first_x = $x; $first_y = $y;}
    $last_x = $x; $last_y = $y;
}

imageline($im,$last_x+$center_x,$last_y+$center_y,$first_x+$center_x,$first_y+$center_y,$red);

//imagestring($im,3,10,10,'loop done',$black);
// output image
Header('Content-type: image/png');
imagepng($im);

// clean up
imagedestroy($im);

?>

Re: Question About a Simple Graph

Posted: Wed Feb 06, 2013 11:22 am
by Weirdan
What you see is likely a rounding error when you explicitly (or implicitly) convert floating point numbers to integers, but might be inherent floating point operation impreciseness as well.

The cheap and dirty trick is to render your graphic into a high-resolution surface (like 4 times the original resolution) and then resample it down to the resolution you need. This will give you nicely antialiased lines as well.

https://www.google.com/search?q=php+antialias+gd will give you plenty of options to do it.

Re: Question About a Simple Graph

Posted: Wed Feb 06, 2013 3:14 pm
by requinix
You can deal with the rounding error specifically by manually round()ing the numbers yourself. In all odds you're facing numbers like 99.9997 which gets truncated to 99 instead of rounded to the 100 it is "supposed" to be.