Enhance GenericResultPoint and move some logic out of qrcode packages for reuse with datamatrix soon

git-svn-id: https://zxing.googlecode.com/svn/trunk@522 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-07-21 21:48:32 +00:00
parent 81ef86b634
commit 5c8b0558e1
3 changed files with 68 additions and 62 deletions

View file

@ -43,7 +43,7 @@ public final class GenericResultPoint implements ResultPoint {
}
public String toString() {
StringBuffer result = new StringBuffer();
StringBuffer result = new StringBuffer(25);
result.append('(');
result.append(posX);
result.append(',');
@ -52,4 +52,66 @@ public final class GenericResultPoint implements ResultPoint {
return result.toString();
}
public boolean equals(Object other) {
if (other instanceof GenericResultPoint) {
GenericResultPoint otherPoint = (GenericResultPoint) other;
return posX == otherPoint.posX && posY == otherPoint.posY;
}
return false;
}
public int hashCode() {
return 31 * Float.floatToIntBits(posX) + Float.floatToIntBits(posY);
}
/**
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
* BC < AC and the angle between BC and BA is less than 180 degrees.
*/
public static void orderBestPatterns(ResultPoint[] patterns) {
// Find distances between pattern centers
float zeroOneDistance = distance(patterns[0], patterns[1]);
float oneTwoDistance = distance(patterns[1], patterns[2]);
float zeroTwoDistance = distance(patterns[0], patterns[2]);
ResultPoint pointA, pointB, pointC;
// Assume one closest to other two is B; A and C will just be guesses at first
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
pointB = patterns[0];
pointA = patterns[1];
pointC = patterns[2];
} else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
pointB = patterns[1];
pointA = patterns[0];
pointC = patterns[2];
} else {
pointB = patterns[2];
pointA = patterns[0];
pointC = patterns[1];
}
// Use cross product to figure out whether A and C are correct or flipped.
if ((pointC.getY() - pointB.getY()) * (pointA.getX() - pointB.getX()) >
(pointC.getX() - pointB.getX()) * (pointA.getY() - pointB.getY())) {
ResultPoint temp = pointA;
pointA = pointC;
pointC = temp;
}
patterns[0] = pointA;
patterns[1] = pointB;
patterns[2] = pointC;
}
/**
* @return distance between two points
*/
public static float distance(ResultPoint pattern1, ResultPoint pattern2) {
float xDiff = pattern1.getX() - pattern2.getX();
float yDiff = pattern1.getY() - pattern2.getY();
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
}
}

View file

@ -22,6 +22,7 @@ import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DetectorResult;
import com.google.zxing.common.GenericResultPoint;
import com.google.zxing.common.GridSampler;
import com.google.zxing.qrcode.decoder.Version;
@ -172,8 +173,8 @@ public final class Detector {
ResultPoint topRight,
ResultPoint bottomLeft,
float moduleSize) throws ReaderException {
int tltrCentersDimension = round(FinderPatternFinder.distance(topLeft, topRight) / moduleSize);
int tlblCentersDimension = round(FinderPatternFinder.distance(topLeft, bottomLeft) / moduleSize);
int tltrCentersDimension = round(GenericResultPoint.distance(topLeft, topRight) / moduleSize);
int tlblCentersDimension = round(GenericResultPoint.distance(topLeft, bottomLeft) / moduleSize);
int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
switch (dimension & 0x03) { // mod 4
case 0:

View file

@ -19,10 +19,10 @@ package com.google.zxing.qrcode.detector;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.ReaderException;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.Collections;
import com.google.zxing.common.Comparator;
import com.google.zxing.common.GenericResultPoint;
import java.util.Hashtable;
import java.util.Vector;
@ -157,7 +157,7 @@ final class FinderPatternFinder {
}
FinderPattern[] patternInfo = selectBestPatterns();
patternInfo = orderBestPatterns(patternInfo);
GenericResultPoint.orderBestPatterns(patternInfo);
return new FinderPatternInfo(patternInfo);
}
@ -503,63 +503,6 @@ final class FinderPatternFinder {
};
}
/**
* <p>Having found three "best" finder patterns we need to decide which is the top-left, top-right,
* bottom-left. We assume that the one closest to the other two is the top-left one; this is not
* strictly true (imagine extreme perspective distortion) but for the moment is a serviceable assumption.
* Lastly we sort top-right from bottom-left by figuring out orientation from vector cross products.</p>
*
* @param patterns three best {@link FinderPattern}s
* @return same {@link FinderPattern}s ordered bottom-left, top-left, top-right
*/
private static FinderPattern[] orderBestPatterns(FinderPattern[] patterns) {
// Find distances between pattern centers
float abDistance = distance(patterns[0], patterns[1]);
float bcDistance = distance(patterns[1], patterns[2]);
float acDistance = distance(patterns[0], patterns[2]);
FinderPattern topLeft;
FinderPattern topRight;
FinderPattern bottomLeft;
// Assume one closest to other two is top left;
// topRight and bottomLeft will just be guesses below at first
if (bcDistance >= abDistance && bcDistance >= acDistance) {
topLeft = patterns[0];
topRight = patterns[1];
bottomLeft = patterns[2];
} else if (acDistance >= bcDistance && acDistance >= abDistance) {
topLeft = patterns[1];
topRight = patterns[0];
bottomLeft = patterns[2];
} else {
topLeft = patterns[2];
topRight = patterns[0];
bottomLeft = patterns[1];
}
// Use cross product to figure out which of other1/2 is the bottom left
// pattern. The vector "top-left -> bottom-left" x "top-left -> top-right"
// should yield a vector with positive z component
if ((bottomLeft.getY() - topLeft.getY()) * (topRight.getX() - topLeft.getX()) <
(bottomLeft.getX() - topLeft.getX()) * (topRight.getY() - topLeft.getY())) {
FinderPattern temp = topRight;
topRight = bottomLeft;
bottomLeft = temp;
}
return new FinderPattern[]{bottomLeft, topLeft, topRight};
}
/**
* @return distance between two points
*/
static float distance(ResultPoint pattern1, ResultPoint pattern2) {
float xDiff = pattern1.getX() - pattern2.getX();
float yDiff = pattern1.getY() - pattern2.getY();
return (float) Math.sqrt((double) (xDiff * xDiff + yDiff * yDiff));
}
/**
* <p>Orders by {@link FinderPattern#getCount()}, descending.</p>
*/