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;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |