ResultPoint.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. /*
  3. * Copyright 2007 ZXing authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace Zxing;
  18. use Zxing\Common\Detector\MathUtils;
  19. /**
  20. * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
  21. * would be the location of a finder pattern or the corner of the barcode, for example.</p>
  22. *
  23. * @author Sean Owen
  24. */
  25. class ResultPoint
  26. {
  27. private $x;
  28. private $y;
  29. public function __construct($x, $y)
  30. {
  31. $this->x = (float)($x);
  32. $this->y = (float)($y);
  33. }
  34. /**
  35. * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
  36. * and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
  37. *
  38. * @param patterns array of three {@code ResultPoint} to order
  39. */
  40. public static function orderBestPatterns($patterns)
  41. {
  42. // Find distances between pattern centers
  43. $zeroOneDistance = self::distance($patterns[0], $patterns[1]);
  44. $oneTwoDistance = self::distance($patterns[1], $patterns[2]);
  45. $zeroTwoDistance = self::distance($patterns[0], $patterns[2]);
  46. $pointA = '';
  47. $pointB = '';
  48. $pointC = '';
  49. // Assume one closest to other two is B; A and C will just be guesses at first
  50. if ($oneTwoDistance >= $zeroOneDistance && $oneTwoDistance >= $zeroTwoDistance) {
  51. $pointB = $patterns[0];
  52. $pointA = $patterns[1];
  53. $pointC = $patterns[2];
  54. } else if ($zeroTwoDistance >= $oneTwoDistance && $zeroTwoDistance >= $zeroOneDistance) {
  55. $pointB = $patterns[1];
  56. $pointA = $patterns[0];
  57. $pointC = $patterns[2];
  58. } else {
  59. $pointB = $patterns[2];
  60. $pointA = $patterns[0];
  61. $pointC = $patterns[1];
  62. }
  63. // Use cross product to figure out whether A and C are correct or flipped.
  64. // This asks whether BC x BA has a positive z component, which is the arrangement
  65. // we want for A, B, C. If it's negative, then we've got it flipped around and
  66. // should swap A and C.
  67. if (self::crossProductZ($pointA, $pointB, $pointC) < 0.0) {
  68. $temp = $pointA;
  69. $pointA = $pointC;
  70. $pointC = $temp;
  71. }
  72. $patterns[0] = $pointA;
  73. $patterns[1] = $pointB;
  74. $patterns[2] = $pointC;
  75. return $patterns;
  76. }
  77. /**
  78. * @param pattern1 first pattern
  79. * @param pattern2 second pattern
  80. *
  81. * @return distance between two points
  82. */
  83. public static function distance($pattern1, $pattern2)
  84. {
  85. return MathUtils::distance($pattern1->x, $pattern1->y, $pattern2->x, $pattern2->y);
  86. }
  87. //@Override
  88. /**
  89. * Returns the z component of the cross product between vectors BC and BA.
  90. */
  91. private static function crossProductZ($pointA,
  92. $pointB,
  93. $pointC)
  94. {
  95. $bX = $pointB->x;
  96. $bY = $pointB->y;
  97. return (($pointC->x - $bX) * ($pointA->y - $bY)) - (($pointC->y - $bY) * ($pointA->x - $bX));
  98. }
  99. //@Override
  100. public final function getX()
  101. {
  102. return (float)($this->x);
  103. }
  104. //@Override
  105. public final function getY()
  106. {
  107. return (float)($this->y);
  108. }
  109. public final function equals($other)
  110. {
  111. if ($other instanceof ResultPoint) {
  112. $otherPoint = $other;
  113. return $this->x == $otherPoint->x && $this->y == $otherPoint->y;
  114. }
  115. return false;
  116. }
  117. public final function hashCode()
  118. {
  119. return 31 * floatToIntBits($this->x) + floatToIntBits($this->y);
  120. }
  121. public final function toString()
  122. {
  123. $result = '';
  124. $result .= ('(');
  125. $result .= ($this->x);
  126. $result .= (',');
  127. $result .= ($this->y);
  128. $result .= (')');
  129. return $result;
  130. }
  131. }