I'm using imagefilledpolygon
to draw an arrow on a GIF image (PHP) and I'd like to make the arrowhead outlined in black. I first create a triangle for the arrow and then draw a thick line at the base of the triangle for the arrow effect.
One solution I think is to create two triangle arrows, the first one being black and slightly larger than the first (to create an outline effect) but I'm not sure how to go about the math of that.
Any help would be great!
Code to create the arrow (head and tail):
function arrow($img, $x1, $y1, $x2, $y2, $alength, $awidth, $color) {
$distance = sqrt(pow($x1 - $x2, 2) + pow($y1 - $y2, 2));
$dx = $x2 + ($x1 - $x2) * $alength / $distance;
$dy = $y2 + ($y1 - $y2) * $alength / $distance;
$k = $awidth / $alength;
$x2o = $x2 - $dx;
$y2o = $dy - $y2;
$x3 = $y2o * $k + $dx;
$y3 = $x2o * $k + $dy;
$x4 = $dx - $y2o * $k;
$y4 = $dy - $x2o * $k;
imagelinethick($img, $x1, $y1, $dx, $dy, $color,3);
return imagefilledpolygon($img, array($x2, $y2, $x3, $y3, $x4, $y4), 3, $color);
}
This function is called for the line of the arrow (just for your reference):
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1)
{
/* this way it works well only for orthogonal lines
imagesetthickness($image, $thick);
return imageline($image, $x1, $y1, $x2, $y2, $color);
*/
if ($thick == 1) {
return imageline($image, $x1, $y1, $x2, $y2, $color);
}
$t = $thick / 2 - 0.5;
if ($x1 == $x2 || $y1 == $y2) {
return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
}
$k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
$a = $t / sqrt(1 + pow($k, 2));
$points = array(
round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
);
imagefilledpolygon($image, $points, 4, $color);
return imagepolygon($image, $points, 4, $color);
}