156 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			156 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			PHP
		
	
	
|  | <?php | ||
|  | /* | ||
|  | * Copyright 2007 ZXing authors | ||
|  | * | ||
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
|  | * you may not use this file except in compliance with the License. | ||
|  | * You may obtain a copy of the License at | ||
|  | * | ||
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | ||
|  | * | ||
|  | * Unless required by applicable law or agreed to in writing, software | ||
|  | * distributed under the License is distributed on an "AS IS" BASIS, | ||
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  | * See the License for the specific language governing permissions and | ||
|  | * limitations under the License. | ||
|  | */ | ||
|  | 
 | ||
|  | namespace Zxing; | ||
|  | 
 | ||
|  | use Zxing\Common\Detector\MathUtils; | ||
|  | 
 | ||
|  | /** | ||
|  |  * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this | ||
|  |  * would be the location of a finder pattern or the corner of the barcode, for example.</p> | ||
|  |  * | ||
|  |  * @author Sean Owen | ||
|  |  */ | ||
|  | class ResultPoint | ||
|  | { | ||
|  |     private $x; | ||
|  |     private $y; | ||
|  | 
 | ||
|  |     public function __construct($x, $y) | ||
|  |     { | ||
|  |         $this->x = (float)($x); | ||
|  |         $this->y = (float)($y); | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC | ||
|  |      * and BC is less than AC, and the angle between BC and BA is less than 180 degrees. | ||
|  |      * | ||
|  |      * @param patterns array of three {@code ResultPoint} to order | ||
|  |      */ | ||
|  |     public static function orderBestPatterns($patterns) | ||
|  |     { | ||
|  | 
 | ||
|  | // Find distances between pattern centers
 | ||
|  |         $zeroOneDistance = self::distance($patterns[0], $patterns[1]); | ||
|  |         $oneTwoDistance  = self::distance($patterns[1], $patterns[2]); | ||
|  |         $zeroTwoDistance = self::distance($patterns[0], $patterns[2]); | ||
|  | 
 | ||
|  |         $pointA = ''; | ||
|  |         $pointB = ''; | ||
|  |         $pointC = ''; | ||
|  | // Assume one closest to other two is B; A and C will just be guesses at first
 | ||
|  |         if ($oneTwoDistance >= $zeroOneDistance && $oneTwoDistance >= $zeroTwoDistance) { | ||
|  |             $pointB = $patterns[0]; | ||
|  |             $pointA = $patterns[1]; | ||
|  |             $pointC = $patterns[2]; | ||
|  |         } else if ($zeroTwoDistance >= $oneTwoDistance && $zeroTwoDistance >= $zeroOneDistance) { | ||
|  |             $pointB = $patterns[1]; | ||
|  |             $pointA = $patterns[0]; | ||
|  |             $pointC = $patterns[2]; | ||
|  |         } else { | ||
|  |             $pointB = $patterns[2]; | ||
|  |             $pointA = $patterns[0]; | ||
|  |             $pointC = $patterns[1]; | ||
|  |         } | ||
|  | 
 | ||
|  | // Use cross product to figure out whether A and C are correct or flipped.
 | ||
|  | // This asks whether BC x BA has a positive z component, which is the arrangement
 | ||
|  | // we want for A, B, C. If it's negative, then we've got it flipped around and
 | ||
|  | // should swap A and C.
 | ||
|  |         if (self::crossProductZ($pointA, $pointB, $pointC) < 0.0) { | ||
|  |             $temp   = $pointA; | ||
|  |             $pointA = $pointC; | ||
|  |             $pointC = $temp; | ||
|  |         } | ||
|  | 
 | ||
|  |         $patterns[0] = $pointA; | ||
|  |         $patterns[1] = $pointB; | ||
|  |         $patterns[2] = $pointC; | ||
|  | 
 | ||
|  |         return $patterns; | ||
|  |     } | ||
|  | 
 | ||
|  |     /** | ||
|  |      * @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); | ||
|  |     } | ||
|  | 
 | ||
|  | //@Override
 | ||
|  | 
 | ||
|  |     /** | ||
|  |      * Returns the z component of the cross product between vectors BC and BA. | ||
|  |      */ | ||
|  |     private static function crossProductZ($pointA, | ||
|  |                                           $pointB, | ||
|  |                                           $pointC) | ||
|  |     { | ||
|  |         $bX = $pointB->x; | ||
|  |         $bY = $pointB->y; | ||
|  | 
 | ||
|  |         return (($pointC->x - $bX) * ($pointA->y - $bY)) - (($pointC->y - $bY) * ($pointA->x - $bX)); | ||
|  |     } | ||
|  | 
 | ||
|  | //@Override
 | ||
|  | 
 | ||
|  |     public final function getX() | ||
|  |     { | ||
|  |         return (float)($this->x); | ||
|  |     } | ||
|  | 
 | ||
|  | //@Override
 | ||
|  | 
 | ||
|  |     public final function getY() | ||
|  |     { | ||
|  |         return (float)($this->y); | ||
|  |     } | ||
|  | 
 | ||
|  |     public final function equals($other) | ||
|  |     { | ||
|  |         if ($other instanceof ResultPoint) { | ||
|  |             $otherPoint = $other; | ||
|  | 
 | ||
|  |             return $this->x == $otherPoint->x && $this->y == $otherPoint->y; | ||
|  |         } | ||
|  | 
 | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     public final function hashCode() | ||
|  |     { | ||
|  |         return 31 * floatToIntBits($this->x) + floatToIntBits($this->y); | ||
|  |     } | ||
|  | 
 | ||
|  |     public final function toString() | ||
|  |     { | ||
|  |         $result = ''; | ||
|  |         $result .= ('('); | ||
|  |         $result .= ($this->x); | ||
|  |         $result .= (','); | ||
|  |         $result .= ($this->y); | ||
|  |         $result .= (')'); | ||
|  | 
 | ||
|  |         return $result; | ||
|  |     } | ||
|  | } |