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;
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>
25 public class ResultPoint {
27 private final float x;
28 private final float y;
30 public ResultPoint(float x, float y) {
35 public final float getX() {
39 public final float getY() {
43 public boolean equals(Object other) {
44 if (other instanceof ResultPoint) {
45 ResultPoint otherPoint = (ResultPoint) other;
46 return x == otherPoint.x && y == otherPoint.y;
51 public int hashCode() {
52 return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);
55 public String toString() {
56 StringBuffer result = new StringBuffer(25);
62 return result.toString();
66 * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
67 * BC < AC and the angle between BC and BA is less than 180 degrees.
69 public static void orderBestPatterns(ResultPoint[] patterns) {
71 // Find distances between pattern centers
72 float zeroOneDistance = distance(patterns[0], patterns[1]);
73 float oneTwoDistance = distance(patterns[1], patterns[2]);
74 float zeroTwoDistance = distance(patterns[0], patterns[2]);
76 ResultPoint pointA, pointB, pointC;
77 // Assume one closest to other two is B; A and C will just be guesses at first
78 if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
82 } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
92 // Use cross product to figure out whether A and C are correct or flipped.
93 // This asks whether BC x BA has a positive z component, which is the arrangement
94 // we want for A, B, C. If it's negative, then we've got it flipped around and
95 // should swap A and C.
96 if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
97 ResultPoint temp = pointA;
102 patterns[0] = pointA;
103 patterns[1] = pointB;
104 patterns[2] = pointC;
109 * @return distance between two points
111 public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
112 float xDiff = pattern1.getX() - pattern2.getX();
113 float yDiff = pattern1.getY() - pattern2.getY();
114 return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
118 * Returns the z component of the cross product between vectors BC and BA.
120 private static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {
123 return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));