Voting

: seven minus five?
(Example: nine)

The Note You're Voting On

Arnapou
17 years ago
I discovered that the GD imagefilledpolygon function is incorrect for some drawing with transparent color (for example red 50% : RGBA = 255, 0, 0, 64).

I tried to draw a complex form with lots of points really near (1 pixel of distance) and a transparent red.

The problem was : some border pixels were not drawn by the imagefilledpolygon but were drawn with imagepolygon !?!?

So I wrote my own imagefilledpolygon function which work very well in all case I tested.

<?php
// $points should be an array of coordinates like that :
$points = array(
array(
0, 0),
array(
100, 50),
array(
90, 100),
array(
50, 50),
array(
70, 30),
array(
10, 10),
);
?>

<?php
function myimagefilledpolygon(& $img, $points, $color) {
$scanline = 99999;
// compute edges
$all_edges = array();
$n = count($points);
for(
$i=0; $i<$n; $i++) {
$p1 = $points[$i];
if (
$i == $n-1) { $p2 = $points[0]; } else { $p2 = $points[$i+1]; }
$x1 = $p1[0]; $y1 = $p1[1];
$x2 = $p2[0]; $y2 = $p2[1];
if (
$y1 != $y2) {
$invslope = ($x2 - $x1)/($y2 - $y1);
if (
$y1 < $y2 ) {
$ymin = $y1;
$xval = $x1;
$ymax = $y2;
} else {
$ymin = $y2;
$xval = $x2;
$ymax = $y1;
}
$all_edges[] = array($ymin, $ymax, $xval, $invslope);
if (
$ymin < $scanline) { $scanline = $ymin; }
} else {
if (
$y1 < $scanline) { $scanline = $y1; }
if (
$y2 < $scanline) { $scanline = $y2; }
}
}
// draw
$active = array();
do {
// add edges to active array
$tmp = array();
$n = count($all_edges);
for(
$i=0; $i<$n; $i++) {
if (
$all_edges[$i][0] == $scanline) {
$active[] = $all_edges[$i];
} else {
$tmp[] = $all_edges[$i];
}
}
$all_edges = $tmp;
// remove previous edges from active array
$tmp = array();
$n = count($active);
for(
$i=0; $i<$n; $i++) {
if (
$active[$i][1] > $scanline) {
$tmp[] = $active[$i];
}
}
$active = $tmp;
// sort active tab
$n = count($active);
for(
$i=0; $i<$n-1; $i++) {
$min = $i;
for(
$k=$i+1; $k<$n; $k++) {
if (
$active[$k][2] < $active[$min][2]) { $min = $k; }
}
if (
$i != $min) {
$tmp = $active[$i];
$active[$i] = $active[$min];
$active[$min] = $tmp;
}
}
// draw
$n = count($active);
for(
$i=0; $i<$n; $i+=2) {
if (
$i+1 < $n) {
if (
$tmp[$i][2] == $active[$i+1][2]) {
imagesetpixel($img, round($active[$i][2]), $scanline, $color);
} else {
imageline($img, round($active[$i][2]), $scanline, round($active[$i+1][2]), $scanline, $color);
}
}
}
// increment x values
$n = count($active);
for(
$i=0; $i<$n; $i++) { $active[$i][2] += $active[$i][3]; }
$scanline++;
} while (
count($all_edges) + count($active) > 0);
}
?>

<< Back to user notes page

To Top