internal static Corner?CreateCorner(Finder topLeftFinder, Finder topRightFinder, Finder bottomLeftFinder) { // try all three possible permutation of three finders for (int index = 0; index < 3; index++) { // TestCorner runs three times to test all posibilities // rotate top left, top right and bottom left if (index != 0) { Finder temp = topLeftFinder; topLeftFinder = topRightFinder; topRightFinder = bottomLeftFinder; bottomLeftFinder = temp; } // top line slope double topLineDeltaX = topRightFinder.Col - topLeftFinder.Col; double topLineDeltaY = topRightFinder.Row - topLeftFinder.Row; // left line slope double leftLineDeltaX = bottomLeftFinder.Col - topLeftFinder.Col; double leftLineDeltaY = bottomLeftFinder.Row - topLeftFinder.Row; double topLineLength = Math.Sqrt(topLineDeltaX * topLineDeltaX + topLineDeltaY * topLineDeltaY); double leftLineLength = Math.Sqrt(leftLineDeltaX * leftLineDeltaX + leftLineDeltaY * leftLineDeltaY); // the short side must be at least 80% of the long side if (Math.Min(topLineLength, leftLineLength) < QRDecoder.CORNER_SIDE_LENGTH_DEV * Math.Max(topLineLength, leftLineLength)) { continue; } // top line vector double topLineSin = topLineDeltaY / topLineLength; double topLineCos = topLineDeltaX / topLineLength; // rotate lines such that top line is parallel to x axis // left line after rotation double newLeftX = topLineCos * leftLineDeltaX + topLineSin * leftLineDeltaY; double newLeftY = -topLineSin * leftLineDeltaX + topLineCos * leftLineDeltaY; // new left line X should be zero (or between +/- 4 deg) if (Math.Abs(newLeftX / leftLineLength) > QRDecoder.CORNER_RIGHT_ANGLE_DEV) { continue; } // swap top line with left line if (newLeftY < 0) { // swap top left with bottom right Finder tempFinder = topRightFinder; topRightFinder = bottomLeftFinder; bottomLeftFinder = tempFinder; } return(new Corner(topLeftFinder, topRightFinder, bottomLeftFinder)); } return(null); }