function imageSmoothArc(&$img, $cx, $cy, $w, $h, $color, $start, $stop) { // Originally written from scratch by Ulrich Mierendorff, 06/2006 // Rewritten and improved, 04/2007, 07/2007 // compared to old version: // + Support for transparency added // + Improved quality of edges & antialiasing // note: This function does not represent the fastest way to draw elliptical // arcs. It was written without reading any papers on that subject. Better // algorithms may be twice as fast or even more. // what it cannot do: It does not support outlined arcs, only filled // Parameters: // $cx - Center of ellipse, X-coord // $cy - Center of ellipse, Y-coord // $w - Width of ellipse ($w >= 2) // $h - Height of ellipse ($h >= 2 ) // $color - Color of ellipse as a four component array with RGBA // $start - Starting angle of the arc, no limited range! // $stop - Stop angle of the arc, no limited range! // $start _can_ be greater than $stop! // If any value is not in the given range, results are undefined! // This script does not use any special algorithms, everything is completely // written from scratch; see http://de.wikipedia.org/wiki/Ellipse for formulas. while ($start < 0) { $start += 2 * M_PI; } while ($stop < 0) { $stop += 2 * M_PI; } while ($start > 2 * M_PI) { $start -= 2 * M_PI; } while ($stop > 2 * M_PI) { $stop -= 2 * M_PI; } if ($start > $stop) { imageSmoothArc($img, $cx, $cy, $w, $h, $color, $start, 2 * M_PI); imageSmoothArc($img, $cx, $cy, $w, $h, $color, 0, $stop); return; } $a = 1.0 * round($w / 2); $b = 1.0 * round($h / 2); $cx = 1.0 * round($cx); $cy = 1.0 * round($cy); $aaAngle = atan($b * $b / ($a * $a) * tan(0.25 * M_PI)); $aaAngleX = $a * cos($aaAngle); $aaAngleY = $b * sin($aaAngle); $a -= 0.5; // looks better... $b -= 0.5; for ($i = 0; $i < 4; $i++) { if ($start < ($i + 1) * M_PI / 2) { if ($start > $i * M_PI / 2) { if ($stop > ($i + 1) * M_PI / 2) { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, ($i + 1) * M_PI / 2, $i); } else { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $start, $stop, $i); break; } } else { if ($stop > ($i + 1) * M_PI / 2) { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i * M_PI / 2, ($i + 1) * M_PI / 2, $i); } else { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $aaAngleX, $aaAngleY, $color, $i * M_PI / 2, $stop, $i); break; } } } } }
function imageSmoothArc(&$img, $cx, $cy, $w, $h, $color, $start, $stop) { while ($start < 0) { $start += 2 * M_PI; } while ($stop < 0) { $stop += 2 * M_PI; } while ($start > 2 * M_PI) { $start -= 2 * M_PI; } while ($stop > 2 * M_PI) { $stop -= 2 * M_PI; } if ($start > $stop) { imageSmoothArc(&$img, $cx, $cy, $w, $h, $color, $start, 2 * M_PI); imageSmoothArc(&$img, $cx, $cy, $w, $h, $color, 0, $stop); return; } $a = 1.0 * round($w / 2); $b = 1.0 * round($h / 2); $cx = 1.0 * round($cx); $cy = 1.0 * round($cy); for ($i = 0; $i < 4; $i++) { if ($start < ($i + 1) * M_PI / 2) { if ($start > $i * M_PI / 2) { if ($stop > ($i + 1) * M_PI / 2) { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $color, $start, ($i + 1) * M_PI / 2, $i); } else { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $color, $start, $stop, $i); break; } } else { if ($stop > ($i + 1) * M_PI / 2) { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $color, $i * M_PI / 2, ($i + 1) * M_PI / 2, $i); } else { imageSmoothArcDrawSegment($img, $cx, $cy, $a, $b, $color, $i * M_PI / 2, $stop, $i); break; } } } } }