/** * <p>This method traces a line from a po$in the image, in the direction towards another point. * It begins in a black region, and keeps going until it finds white, then black, then white again. * It reports the distance from the start to this point.</p> * * <p>This is used when figuring out how wide a finder pattern is, when the finder pattern * may be skewed or rotated.</p> */ private function sizeOfBlackWhiteBlackRun($fromX, $fromY, $toX, $toY) { // Mild variant of Bresenham's algorithm; // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm $steep = abs($toY - $fromY) > abs($toX - $fromX); if ($steep) { $temp = $fromX; $fromX = $fromY; $fromY = $temp; $temp = $toX; $toX = $toY; $toY = $temp; } $dx = abs($toX - $fromX); $dy = abs($toY - $fromY); $error = -$dx / 2; $xstep = $fromX < $toX ? 1 : -1; $ystep = $fromY < $toY ? 1 : -1; // In black pixels, looking for white, first or second time. $state = 0; // Loop up until x == toX, but not beyond $xLimit = $toX + $xstep; for ($x = $fromX, $y = $fromY; $x != $xLimit; $x += $xstep) { $realX = $steep ? $y : $x; $realY = $steep ? $x : $y; // Does current pixel mean we have moved white to black or vice versa? // Scanning black in state 0,2 and white in state 1, so if we find the wrong // color, advance to next state or end if we are in state 2 already if (($state == 1) == $this->image->get($realX, $realY)) { if ($state == 2) { return MathUtils::distance($x, $y, $fromX, $fromY); } $state++; } $error += $dy; if ($error > 0) { if ($y == $toY) { break; } $y += $ystep; $error -= $dx; } } // Found black-white-black; give the benefit of the doubt that the next pixel outside the image // is "white" so this last po$at (toX+xStep,toY) is the right ending. This is really a // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. if ($state == 2) { return MathUtils::distance($toX + $xstep, $toY, $fromX, $fromY); } // else we didn't find even black-white-black; no estimate is really possible return NAN; }
/** * @param pattern1 first pattern * @param pattern2 second pattern * @return distance between two points */ public static function distance($pattern1, $pattern2) { return MathUtils::distance($pattern1->x, $pattern1->y, $pattern2->x, $pattern2->y); }