📄 finderpattern.java
字号:
sincos[0] = ((remotePoint.getY() - originPoint.getY()) << QRCodeImageReader.DECIMAL_POINT) / r; //Sin
sincos[1] = ((remotePoint.getX() - originPoint.getX()) << QRCodeImageReader.DECIMAL_POINT) / r; //Cos
// sincos[0] = (sincos[0] == 0) ? 1 : sincos[0];
// sincos[1] = (sincos[1] == 0) ? 1 : sincos[1];
return sincos;
}
static Point[] getCenter(Line[] crossLines)
throws FinderPatternNotFoundException {
Vector centers = new Vector();
for (int i = 0; i < crossLines.length - 1; i++) {
Line compareLine = crossLines[i];
for (int j = i + 1; j < crossLines.length; j++) {
Line comparedLine = crossLines[j];
if (Line.isCross(compareLine, comparedLine)) {
int x = 0;
int y = 0;
if (compareLine.isHorizontal()) {
x = compareLine.getCenter().getX();
y = comparedLine.getCenter().getY();
}
else {
x = comparedLine.getCenter().getX();
y = compareLine.getCenter().getY();
}
centers.addElement(new Point(x,y));
}
}
}
Point[] foundPoints = new Point[centers.size()];
for (int i = 0; i < foundPoints.length; i++) {
foundPoints[i] = (Point)centers.elementAt(i);
}
if (foundPoints.length == 3) {
canvas.drawPolygon(foundPoints, Color.LIGHTRED);
return foundPoints;
}
else
throw new FinderPatternNotFoundException();
}
//奺埵抲梫慺専弌僷僞乕儞偺拞怱揰傪奿擺偟偨攝楍傪丄
//嵍忋 points[0] 塃忋 points[1] 嵍壓 points[2]偵側傞傛偆偵僜乕僩偡傞
static Point[] sort(Point[] centers, int[] sincos) {
int sin = sincos[0];
int cos = sincos[1];
Point[] sortedCenters = new Point[3];
int quadant = getURQuadant(sincos);
switch (quadant) {
case 1:
sortedCenters[1] = getPointAtSide(centers, Point.RIGHT, Point.BOTTOM);
sortedCenters[2] = getPointAtSide(centers, Point.BOTTOM, Point.LEFT);
break;
case 2:
sortedCenters[1] = getPointAtSide(centers, Point.BOTTOM, Point.LEFT);
sortedCenters[2] = getPointAtSide(centers, Point.TOP, Point.LEFT);
break;
case 3:
sortedCenters[1] = getPointAtSide(centers, Point.LEFT, Point.TOP);
sortedCenters[2] = getPointAtSide(centers, Point.RIGHT, Point.TOP);
break;
case 4:
sortedCenters[1] = getPointAtSide(centers, Point.TOP, Point.RIGHT);
sortedCenters[2] = getPointAtSide(centers, Point.BOTTOM, Point.RIGHT);
break;
}
//嵟屻偵嵍忋偺僷僞乕儞傪挷傋傞
for (int i = 0; i < centers.length; i++) {
if (!centers[i].equals(sortedCenters[1]) &&
!centers[i].equals(sortedCenters[2])) {
sortedCenters[0] = centers[i];
}
}
return sortedCenters;
}
static int getURQuadant(int[] sincos) {
int sin = sincos[0];
int cos = sincos[1];
if (sin >= 0 && cos > 0)
return 1;
else if (sin > 0 && cos <= 0)
return 2;
else if (sin <= 0 && cos < 0)
return 3;
else if (sin < 0 && cos >= 0)
return 4;
return 0;
}
static Point getPointAtSide(Point[] points, int side1, int side2) {
Point sidePoint = new Point();
int x = ((side1 == Point.RIGHT || side2 == Point.RIGHT) ? 0 : Integer.MAX_VALUE);
int y = ((side1 == Point.BOTTOM || side2 == Point.BOTTOM) ? 0 : Integer.MAX_VALUE);
sidePoint = new Point(x, y);
for (int i = 0; i < points.length; i++) {
switch (side1) {
case Point.RIGHT:
if (sidePoint.getX() < points[i].getX()) {
sidePoint = points[i];
}
else if (sidePoint.getX() == points[i].getX()) {
if (side2 == Point.BOTTOM) {
if (sidePoint.getY() < points[i].getY()) {
sidePoint = points[i];
}
}
else {
if (sidePoint.getY() > points[i].getY()) {
sidePoint = points[i];
}
}
}
break;
case Point.BOTTOM:
if (sidePoint.getY() < points[i].getY()) {
sidePoint = points[i];
}
else if (sidePoint.getY() == points[i].getY()) {
if (side2 == Point.RIGHT) {
if (sidePoint.getX() < points[i].getX()) {
sidePoint = points[i];
}
}
else {
if (sidePoint.getX() > points[i].getX()) {
sidePoint = points[i];
}
}
}
break;
case Point.LEFT:
if (sidePoint.getX() > points[i].getX()) {
sidePoint = points[i];
}
else if (sidePoint.getX() == points[i].getX()) {
if (side2 == Point.BOTTOM) {
if (sidePoint.getY() < points[i].getY()) {
sidePoint = points[i];
}
}
else {
if (sidePoint.getY() > points[i].getY()) {
sidePoint = points[i];
}
}
}
break;
case Point.TOP:
if (sidePoint.getY() > points[i].getY()) {
sidePoint = points[i];
}
else if (sidePoint.getY() == points[i].getY()) {
if (side2 == Point.RIGHT) {
if (sidePoint.getX() < points[i].getX()) {
sidePoint = points[i];
}
}
else {
if (sidePoint.getX() > points[i].getX()) {
sidePoint = points[i];
}
}
}
break;
}
}
return sidePoint;
}
//埵抲梫慺専弌僷僞乕儞偺暆傪媮傔傞
static int[] getWidth(Line[] crossLines, Point[] centers, int[] sincos) {
int sin = sincos[0];
int cos = sincos[1];
int[] width = new int[3];
for (int i = 0; i < crossLines.length; i++) {
for (int j = i; j < crossLines.length; j++) {
if (Line.isCross(crossLines[i], crossLines[j])) {
if (crossLines[i].isHorizontal()) {
for (int k = 0; k < centers.length; k++) {
if (crossLines[i].getCenter().getX() ==
centers[k].getX() &&
crossLines[j].getCenter().getY() ==
centers[k].getY()) {
int y = 0;
if (Math.abs(sin) < (1 << QRCodeImageReader.DECIMAL_POINT) / 2) //Threshold 45 degree
y = (crossLines[i].getLength() * sin) >> QRCodeImageReader.DECIMAL_POINT;
else
y = (crossLines[i].getLength() * cos) >> QRCodeImageReader.DECIMAL_POINT;
int r = crossLines[i].getLength();
width[k] = QRCodeUtility.sqrt(r * r - y * y);
}
}
}
else {
for (int k = 0; k < centers.length; k++) {
if (crossLines[j].getCenter().getX() ==
centers[k].getX() &&
crossLines[i].getCenter().getY() ==
centers[k].getY()) {
int y = 0;
//戞1徾尷傑偨偼戞3徾尷
if (Math.abs(sin) < 2897) //Threshold 45 degree
y = crossLines[i].getLength() * sin >> 12;
else
y = crossLines[i].getLength() * cos >> 12;
int r = crossLines[j].getLength();
width[k] = QRCodeUtility.sqrt(r * r - y * y);
}
}
}
}
}
}
return width;
}
//宆斣傪壖偵媮傔傞
static int calcRoughVersion(Point[] center, int[] width) {
final int dp = QRCodeImageReader.DECIMAL_POINT;
int lengthAdditionalLine = (new Line(center[UL], center[UR]).getLength()) << dp ;
//System.out.println("lengthAdditionalLine" + Integer.toString(lengthAdditionalLine));
int avarageWidth = ((width[UL] + width[UR]) << dp) / 14;
//System.out.println("avarageWidth:" + Integer.toBinaryString(avarageWidth));
int roughVersion = ((lengthAdditionalLine / avarageWidth) - 10) / 4;
if (((lengthAdditionalLine / avarageWidth) - 10) % 4 >= 2) {
roughVersion++;
}
//if (tempVersion % 4096 < 2048)
//tempVersion >>= QRCodeImageReader.DECIMAL_POINT;
//else {
// tempVersion >>= QRCodeImageReader.DECIMAL_POINT;
// tempVersion++; //寘棊偪懳嶔
//}
//if (tempVersion <= 6)
return roughVersion;
}
static int calcExactVersion(Point[] centers, int[] sincos, int[] moduleSize, boolean[][] image)
throws InvalidVersionInformationException,
UnsupportedVersionException {
boolean[] versionInformation = new boolean[18];
//int offsetX = -(moduleSize * 8) >> 12;
//int offsetY = -(moduleSize * 3) >> 12;
Point[] points = new Point[18];
int targetX, targetY;
int sin = sincos[0];
int cos = sincos[1];
Axis axis = new Axis(sin, cos, moduleSize[0]); //UR
axis.setOrigin(centers[UR]);
for (int y = 0; y < 6; y++) {
for (int x = 0; x < 3; x++) {
//targetX = finderX + ((moduleSize * (x-7)) >> QRCodeImageReader.DECIMAL_POINT);
targetX = axis.translate(x - 7, 0).getX() + 1;
//targetY = finderY + ((moduleSize * (y-3)) >> QRCodeImageReader.DECIMAL_POINT);
targetY = axis.translate(0, y - 3).getY() + 1;
versionInformation[x + y * 3] = image[targetX][targetY];
points[x + y * 3] = new Point(targetX, targetY);
//System.out.print(points[x + y * 3]);
//points[x + y * 3] = axis.translate(x - 7, y - 3);
}
//System.out.println("");
}
canvas.drawPoints(points, Color.LIGHTRED);
int exactVersion = 0;
try {
exactVersion = checkVersionInfo(versionInformation);
} catch (VersionInformationException e) {
canvas.println("Version info error. now retry with other place one.");
axis.setOrigin(centers[DL]);
axis.setModulePitch(moduleSize[1]); //DL
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 3; y++) {
//targetX = finderX + ((moduleSize * (x-7)) >> QRCodeImageReader.DECIMAL_POINT);
targetX = axis.translate(x - 3, 0).getX();
//targetY = finderY + ((moduleSize * (y-3)) >> QRCodeImageReader.DECIMAL_POINT);
targetY = axis.translate(0, y - 7).getY();
versionInformation[y + x * 3] = image[targetX][targetY];
points[x + y * 3] = new Point(targetX, targetY);
//System.out.println(points[x + y * 3]);
//canvas.drawCross(points[x + y * 3], Color.LIGHTRED);
//System.out.print(points[x + y * 3]);
//points[x + y * 3] = axis.translate(x - 7, y - 3);
}
//System.out.println("");
}
canvas.drawPoints(points, Color.LIGHTRED);
try {
exactVersion = checkVersionInfo(versionInformation);
} catch (VersionInformationException e2) {
e.printStackTrace();
throw e2;
}
}
//System.out.println("VersionInfo error");
return exactVersion;
}
static int checkVersionInfo(boolean[] target)
throws InvalidVersionInformationException{
int errorCount = 0, versionBase;
for (versionBase = 0; versionBase < VersionInfoBit.length; versionBase++) {
errorCount = 0;
for (int j = 0; j < 18; j++) {
if (target[j] ^ (VersionInfoBit[versionBase] >> j) % 2 == 1)
errorCount++;
}
if (errorCount <= 3) break;
}
if (errorCount <= 3)
return 7 + versionBase;
else
throw new InvalidVersionInformationException();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -