2 * Copyright 2007 ZXing authors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.zxing;
19 import com.google.zxing.common.detector.MathUtils;
22 * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
23 * would be the location of a finder pattern or the corner of the barcode, for example.</p>
27 public class ResultPoint {
29 private final float x;
30 private final float y;
32 public ResultPoint(float x, float y) {
37 public final float getX() {
41 public final float getY() {
46 public final boolean equals(Object other) {
47 if (other instanceof ResultPoint) {
48 ResultPoint otherPoint = (ResultPoint) other;
49 return x == otherPoint.x && y == otherPoint.y;
55 public final int hashCode() {
56 return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
60 public final String toString() {
61 StringBuilder result = new StringBuilder(25);
67 return result.toString();
71 * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
72 * BC < AC and the angle between BC and BA is less than 180 degrees.
74 public static void orderBestPatterns(ResultPoint[] patterns) {
76 // Find distances between pattern centers
77 float zeroOneDistance = distance(patterns[0], patterns[1]);
78 float oneTwoDistance = distance(patterns[1], patterns[2]);
79 float zeroTwoDistance = distance(patterns[0], patterns[2]);
84 // Assume one closest to other two is B; A and C will just be guesses at first
85 if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
89 } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
99 // Use cross product to figure out whether A and C are correct or flipped.
100 // This asks whether BC x BA has a positive z component, which is the arrangement
101 // we want for A, B, C. If it's negative, then we've got it flipped around and
102 // should swap A and C.
103 if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
104 ResultPoint temp = pointA;
109 patterns[0] = pointA;
110 patterns[1] = pointB;
111 patterns[2] = pointC;
116 * @return distance between two points
118 public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
119 return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);
123 * Returns the z component of the cross product between vectors BC and BA.
125 private static float crossProductZ(ResultPoint pointA,
127 ResultPoint pointC) {
130 return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));