2 * Copyright 2008 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.common;
19 import com.google.zxing.ResultPoint;
22 * <p>Simple implementation of {@link ResultPoint} for applications that don't need
23 * to use anything more complex.</p>
25 * @author dswitkin@google.com (Daniel Switkin)
27 public final class GenericResultPoint implements ResultPoint {
29 private final float posX;
30 private final float posY;
32 public GenericResultPoint(float posX, float posY) {
45 public String toString() {
46 StringBuffer result = new StringBuffer(25);
52 return result.toString();
55 public boolean equals(Object other) {
56 if (other instanceof GenericResultPoint) {
57 GenericResultPoint otherPoint = (GenericResultPoint) other;
58 return posX == otherPoint.posX && posY == otherPoint.posY;
63 public int hashCode() {
64 return 31 * Float.floatToIntBits(posX) + Float.floatToIntBits(posY);
68 * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
69 * BC < AC and the angle between BC and BA is less than 180 degrees.
71 public static void orderBestPatterns(ResultPoint[] patterns) {
73 // Find distances between pattern centers
74 float zeroOneDistance = distance(patterns[0], patterns[1]);
75 float oneTwoDistance = distance(patterns[1], patterns[2]);
76 float zeroTwoDistance = distance(patterns[0], patterns[2]);
78 ResultPoint pointA, pointB, pointC;
79 // Assume one closest to other two is B; A and C will just be guesses at first
80 if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
84 } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
94 // Use cross product to figure out whether A and C are correct or flipped.
95 // This asks whether BC x BA has a positive z component, which is the arrangement
96 // we want for A, B, C. If it's negative, then we've got it flipped around and
97 // should swap A and C.
98 if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
99 ResultPoint temp = pointA;
104 patterns[0] = pointA;
105 patterns[1] = pointB;
106 patterns[2] = pointC;
111 * @return distance between two points
113 public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
114 float xDiff = pattern1.getX() - pattern2.getX();
115 float yDiff = pattern1.getY() - pattern2.getY();
116 return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
120 * Returns the z component of the cross product between vectors BC and BA.
122 public static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {
123 float bX = pointB.getX();
124 float bY = pointB.getY();
125 return ((pointC.getX() - bX) * (pointA.getY() - bY)) - ((pointC.getY() - bY) * (pointA.getX() - bX));