You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ResultPoint.cs 6.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright 2007 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. using System;
  17. using ZXing.Common.Detector;
  18. namespace ZXing
  19. {
  20. /// <summary>
  21. /// Encapsulates a point of interest in an image containing a barcode. Typically, this
  22. /// would be the location of a finder pattern or the corner of the barcode, for example.
  23. /// </summary>
  24. /// <author>Sean Owen</author>
  25. /// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source</author>
  26. public class ResultPoint
  27. {
  28. private readonly float x;
  29. private readonly float y;
  30. private readonly byte[] bytesX;
  31. private readonly byte[] bytesY;
  32. private String toString;
  33. /// <summary>
  34. /// Initializes a new instance of the <see cref="ResultPoint"/> class.
  35. /// </summary>
  36. public ResultPoint()
  37. {
  38. }
  39. /// <summary>
  40. /// Initializes a new instance of the <see cref="ResultPoint"/> class.
  41. /// </summary>
  42. /// <param name="x">The x.</param>
  43. /// <param name="y">The y.</param>
  44. public ResultPoint(float x, float y)
  45. {
  46. this.x = x;
  47. this.y = y;
  48. // calculate only once for GetHashCode
  49. bytesX = BitConverter.GetBytes(x);
  50. bytesY = BitConverter.GetBytes(y);
  51. }
  52. /// <summary>
  53. /// Gets the X.
  54. /// </summary>
  55. virtual public float X
  56. {
  57. get
  58. {
  59. return x;
  60. }
  61. }
  62. /// <summary>
  63. /// Gets the Y.
  64. /// </summary>
  65. virtual public float Y
  66. {
  67. get
  68. {
  69. return y;
  70. }
  71. }
  72. /// <summary>
  73. /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
  74. /// </summary>
  75. /// <param name="other">The <see cref="System.Object"/> to compare with this instance.</param>
  76. /// <returns>
  77. /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
  78. /// </returns>
  79. public override bool Equals(Object other)
  80. {
  81. var otherPoint = other as ResultPoint;
  82. if (otherPoint == null)
  83. return false;
  84. return x == otherPoint.x && y == otherPoint.y;
  85. }
  86. /// <summary>
  87. /// Returns a hash code for this instance.
  88. /// </summary>
  89. /// <returns>
  90. /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
  91. /// </returns>
  92. public override int GetHashCode()
  93. {
  94. return 31 * ((bytesX[0] << 24) + (bytesX[1] << 16) + (bytesX[2] << 8) + bytesX[3]) +
  95. (bytesY[0] << 24) + (bytesY[1] << 16) + (bytesY[2] << 8) + bytesY[3];
  96. }
  97. /// <summary>
  98. /// Returns a <see cref="System.String"/> that represents this instance.
  99. /// </summary>
  100. /// <returns>
  101. /// A <see cref="System.String"/> that represents this instance.
  102. /// </returns>
  103. public override String ToString()
  104. {
  105. if (toString == null)
  106. {
  107. var result = new System.Text.StringBuilder(25);
  108. result.AppendFormat(System.Globalization.CultureInfo.CurrentUICulture, "({0}, {1})", x, y);
  109. toString = result.ToString();
  110. }
  111. return toString;
  112. }
  113. /// <summary>
  114. /// Orders an array of three ResultPoints in an order [A,B,C] such that AB &lt; AC and
  115. /// BC &lt; AC and the angle between BC and BA is less than 180 degrees.
  116. /// </summary>
  117. public static void orderBestPatterns(ResultPoint[] patterns)
  118. {
  119. // Find distances between pattern centers
  120. float zeroOneDistance = distance(patterns[0], patterns[1]);
  121. float oneTwoDistance = distance(patterns[1], patterns[2]);
  122. float zeroTwoDistance = distance(patterns[0], patterns[2]);
  123. ResultPoint pointA, pointB, pointC;
  124. // Assume one closest to other two is B; A and C will just be guesses at first
  125. if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance)
  126. {
  127. pointB = patterns[0];
  128. pointA = patterns[1];
  129. pointC = patterns[2];
  130. }
  131. else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance)
  132. {
  133. pointB = patterns[1];
  134. pointA = patterns[0];
  135. pointC = patterns[2];
  136. }
  137. else
  138. {
  139. pointB = patterns[2];
  140. pointA = patterns[0];
  141. pointC = patterns[1];
  142. }
  143. // Use cross product to figure out whether A and C are correct or flipped.
  144. // This asks whether BC x BA has a positive z component, which is the arrangement
  145. // we want for A, B, C. If it's negative, then we've got it flipped around and
  146. // should swap A and C.
  147. if (crossProductZ(pointA, pointB, pointC) < 0.0f)
  148. {
  149. ResultPoint temp = pointA;
  150. pointA = pointC;
  151. pointC = temp;
  152. }
  153. patterns[0] = pointA;
  154. patterns[1] = pointB;
  155. patterns[2] = pointC;
  156. }
  157. /// <returns>
  158. /// distance between two points
  159. /// </returns>
  160. public static float distance(ResultPoint pattern1, ResultPoint pattern2)
  161. {
  162. return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
  163. }
  164. /// <summary>
  165. /// Returns the z component of the cross product between vectors BC and BA.
  166. /// </summary>
  167. private static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC)
  168. {
  169. float bX = pointB.x;
  170. float bY = pointB.y;
  171. return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
  172. }
  173. }
  174. }