img = $img; $img->initpixelcache(); $this->pixel = $img->pixel($channel); $this->color = $img->colorallocate(255, 0, 0); } public function find() { $best = 0; $img = $this->img; //for ($r = (min($img->width(), $img->height()) / 2); $r > 10; $r--) { for ($r = 29; $r >= 23; $r--) { echo "r".$r."\n"; // TODO: debug code for ($x = $r; $x < $img->width() - $r; $x++) { for ($y = $r; $y < $img->height() - $r; $y++) { if (($fit = $this->checkPossibility($x, $y, $r)) && $fit > $best) { $best = $fit; $bx = $x; $by = $y; $br = $r; echo "match ".round($fit)."%: x $x y $y r $r\n"; // TODO: debug code } } } } echo "result ".round($best)."%: x $bx y $by r $br\n"; // TODO: debug code $img->ellipse($bx, $by, 2*$br, 2*$br, $this->color); return $img; } protected function checkPossibility($xCenter, $yCenter, $r) { $this->matches = 0; $this->pixelcount = 0; $this->circleMidPoint($xCenter, $yCenter, $r); return ($this->matches / $this->pixelcount / 2.55); } private function match($x, $y) { //if($x < 0 || $y < 0 || $x >= $this->img->width() || $y >= $this->img->height()) // return; $intensity = reset($this->pixel[$x][$y]); $this->pixelcount++; $this->matches += $intensity; } /* adopted from and explained at http://www.cs.unc.edu/~mcmillan/comp136/Lecture7/circle.html */ private function circlePoints($cx, $cy, $x, $y) { if ($x == 0) { $this->match($cx, $cy + $y); $this->match($cx, $cy - $y); $this->match($cx + $y, $cy); $this->match($cx - $y, $cy); } else if ($x == $y) { $this->match($cx + $x, $cy + $y); $this->match($cx - $x, $cy + $y); $this->match($cx + $x, $cy - $y); $this->match($cx - $x, $cy - $y); } else if ($x < $y) { $this->match($cx + $x, $cy + $y); $this->match($cx - $x, $cy + $y); $this->match($cx + $x, $cy - $y); $this->match($cx - $x, $cy - $y); $this->match($cx + $y, $cy + $x); $this->match($cx - $y, $cy + $x); $this->match($cx + $y, $cy - $x); $this->match($cx - $y, $cy - $x); } } protected function circleMidpoint($xCenter, $yCenter, $r) { $x = 0; $y = $r; $p = (5 - $r*4) / 4; $this->circlePoints($xCenter, $yCenter, $x, $y); while ($x < $y) { $x++; if ($p < 0) { $p += 2*$x+1; } else { $y--; $p += 2*($x-$y)+1; } $this->circlePoints($xCenter, $yCenter, $x, $y); } } }