Committed C# port from Mohamad
[zxing.git] / csharp / common / GenericResultPoint.cs
1 /*\r
2 * Copyright 2008 ZXing authors\r
3 *\r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5 * you may not use this file except in compliance with the License.\r
6 * You may obtain a copy of the License at\r
7 *\r
8 *      http://www.apache.org/licenses/LICENSE-2.0\r
9 *\r
10 * Unless required by applicable law or agreed to in writing, software\r
11 * distributed under the License is distributed on an "AS IS" BASIS,\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 * See the License for the specific language governing permissions and\r
14 * limitations under the License.\r
15 */\r
16 namespace com.google.zxing.common\r
17 {\r
18     using System;\r
19     using System.Text;\r
20 \r
21     /// <summary> A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a\r
22     /// unsigned container, it's up to you to do byteValue & 0xff at each location.\r
23     /// *\r
24     /// JAVAPORT: I'm not happy about the argument ordering throughout the file, as I always like to have\r
25     /// the horizontal component first, but this is for compatibility with the C++ code. The original\r
26     /// code was a 2D array of ints, but since it only ever gets assigned -1, 0, and 1, I'm going to use\r
27     /// less memory and go with bytes.\r
28     /// *\r
29     /// </summary>\r
30     /// <author>  dswitkin@google.com (Daniel Switkin)\r
31     /// \r
32     /// </author>\r
33     public sealed class GenericResultPoint : ResultPoint\r
34     { \r
35           private float posX;\r
36           private float posY;\r
37 \r
38           public GenericResultPoint(float posX, float posY) {\r
39             this.posX = posX;\r
40             this.posY = posY;\r
41           }\r
42 \r
43           public float getX() {\r
44             return posX;\r
45           }\r
46 \r
47           public float getY() {\r
48             return posY;\r
49           }\r
50 \r
51           public String toString() {\r
52             StringBuilder result = new StringBuilder(25);\r
53             result.Append('(');\r
54             result.Append(posX);\r
55             result.Append(',');\r
56             result.Append(posY);\r
57             result.Append(')');\r
58             return result.ToString();\r
59           }\r
60 \r
61           public bool equals(Object other) {\r
62             \r
63             if (other.GetType() == typeof(GenericResultPoint)) {\r
64               GenericResultPoint otherPoint = (GenericResultPoint) other;\r
65               return posX == otherPoint.posX && posY == otherPoint.posY;\r
66             }\r
67             return false;\r
68           }\r
69 \r
70           public int hashCode() {\r
71               return 31 * posX.GetHashCode() + posY.GetHashCode();\r
72           }\r
73 \r
74             /**\r
75            * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and\r
76            * BC < AC and the angle between BC and BA is less than 180 degrees.\r
77            */\r
78           public static void orderBestPatterns(ResultPoint[] patterns) {\r
79 \r
80             // Find distances between pattern centers\r
81             float zeroOneDistance = distance(patterns[0], patterns[1]);\r
82             float oneTwoDistance = distance(patterns[1], patterns[2]);\r
83             float zeroTwoDistance = distance(patterns[0], patterns[2]);\r
84 \r
85             ResultPoint pointA, pointB, pointC;\r
86             // Assume one closest to other two is B; A and C will just be guesses at first\r
87             if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {\r
88               pointB = patterns[0];\r
89               pointA = patterns[1];\r
90               pointC = patterns[2];\r
91             } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {\r
92               pointB = patterns[1];\r
93               pointA = patterns[0];\r
94               pointC = patterns[2];\r
95             } else {\r
96               pointB = patterns[2];\r
97               pointA = patterns[0];\r
98               pointC = patterns[1];\r
99             }\r
100 \r
101             // Use cross product to figure out whether A and C are correct or flipped.\r
102             // This asks whether BC x BA has a positive z component, which is the arrangement\r
103             // we want for A, B, C. If it's negative, then we've got it flipped around and\r
104             // should swap A and C.\r
105             if (crossProductZ(pointA, pointB, pointC) < 0.0f) {\r
106               ResultPoint temp = pointA;\r
107               pointA = pointC;\r
108               pointC = temp;\r
109             }\r
110 \r
111             patterns[0] = pointA;\r
112             patterns[1] = pointB;\r
113             patterns[2] = pointC;\r
114           }\r
115 \r
116 \r
117           /**\r
118            * @return distance between two points\r
119            */\r
120           public static float distance(ResultPoint pattern1, ResultPoint pattern2) {\r
121             float xDiff = pattern1.getX() - pattern2.getX();\r
122             float yDiff = pattern1.getY() - pattern2.getY();\r
123             return (float) Math.Sqrt((double) (xDiff * xDiff + yDiff * yDiff));\r
124           }\r
125 \r
126           /**\r
127            * Returns the z component of the cross product between vectors BC and BA.\r
128            */\r
129           public static float crossProductZ(ResultPoint pointA, ResultPoint pointB, ResultPoint pointC) {\r
130             float bX = pointB.getX();\r
131             float bY = pointB.getY();\r
132             return ((pointC.getX() - bX) * (pointA.getY() - bY)) - ((pointC.getY() - bY) * (pointA.getX() - bX));\r
133           }     \r
134     \r
135     }\r
136 }