@@ -47,8 +47,8 @@ public final strictfp class S2 {
4747 * {@code (0.5 <= |v|*2^(-exp) < 1)}. If v is zero, return 0.
4848 *
4949 * <p>Note that this arguably a bad definition of exponent because it makes
50- * {@code exp(9) == 4}. In decimal this would be like saying that the exponent
51- * of 1234 is 4, when in scientific 'exponent' notation 1234 is
50+ * {@code exp(9) == 4}. In decimal this would be like saying that the
51+ * exponent of 1234 is 4, when in scientific 'exponent' notation 1234 is
5252 * {@code 1.234 x 10^3}.
5353 *
5454 * TODO(dbeaumont): Replace this with "DoubleUtils.getExponent(v) - 1" ?
@@ -62,32 +62,79 @@ static int exp(double v) {
6262 return (int ) ((EXPONENT_MASK & bits ) >> EXPONENT_SHIFT ) - 1022 ;
6363 }
6464
65- /**
66- * kPosToOrientation[pos] -> orientation_modifier
67- *
68- * Return a modifier indicating how the orientation of the child subcell with
69- * the given traversal position [0..3] is related to the orientation of the
70- * parent cell. The modifier should be XOR-ed with the parent orientation to
71- * obtain the curve orientation in the child.
72- *
73- */
74- static final int [] POS_TO_ORIENTATION = {SWAP_MASK , 0 , 0 , INVERT_MASK + SWAP_MASK };
65+ /** Mapping Hilbert traversal order to orientation adjustment mask. */
66+ private static final int [] POS_TO_ORIENTATION =
67+ {SWAP_MASK , 0 , 0 , INVERT_MASK + SWAP_MASK };
7568
7669 /**
70+ * Returns an XOR bit mask indicating how the orientation of a child subcell
71+ * is related to the orientation of its parent cell. The returned value can
72+ * be XOR'd with the parent cell's orientation to give the orientation of
73+ * the child cell.
7774 *
78- * kPosToIJ[orientation][pos] -> ij // // Return the (i,j) index of the
79- * subcell at the given position 'pos' in the // Hilbert curve traversal order
80- * with the given orientation. This is the // inverse of the previous table:
81- * kPosToIJ[r][kIJtoPos[r][ij]] == ij
75+ * @param position the position of the subcell in the Hilbert traversal, in
76+ * the range [0,3].
77+ * @return a bit mask containing some combination of {@link #SWAP_MASK} and
78+ * {@link #INVERT_MASK}.
79+ * @throws IllegalArgumentException if position is out of bounds.
8280 */
83- public static final int [][] POS_TO_IJ = {
84- // 0 1 2 3
81+ public static int posToOrientation (int position ) {
82+ Preconditions .checkArgument (0 <= position && position < 4 );
83+ return POS_TO_ORIENTATION [position ];
84+ }
85+
86+ /** Mapping from cell orientation + Hilbert traversal to IJ-index. */
87+ private static final int [][] POS_TO_IJ = {
88+ // 0 1 2 3
8589 {0 , 1 , 3 , 2 }, // canonical order: (0,0), (0,1), (1,1), (1,0)
8690 {0 , 2 , 3 , 1 }, // axes swapped: (0,0), (1,0), (1,1), (0,1)
8791 {3 , 2 , 0 , 1 }, // bits inverted: (1,1), (1,0), (0,0), (0,1)
8892 {3 , 1 , 0 , 2 }, // swapped & inverted: (1,1), (0,1), (0,0), (1,0)
8993 };
9094
95+ /**
96+ * Return the IJ-index of the subcell at the given position in the Hilbert
97+ * curve traversal with the given orientation. This is the inverse of
98+ * {@link #ijToPos}.
99+ *
100+ * @param orientation the subcell orientation, in the range [0,3].
101+ * @param position the position of the subcell in the Hilbert traversal, in
102+ * the range [0,3].
103+ * @return the IJ-index where {@code 0->(0,0), 1->(0,1), 2->(1,0), 3->(1,1)}.
104+ * @throws IllegalArgumentException if either parameter is out of bounds.
105+ */
106+ public static int posToIJ (int orientation , int position ) {
107+ Preconditions .checkArgument (0 <= orientation && orientation < 4 );
108+ Preconditions .checkArgument (0 <= position && position < 4 );
109+ return POS_TO_IJ [orientation ][position ];
110+ }
111+
112+ /** Mapping from Hilbert traversal order + cell orientation to IJ-index. */
113+ private static final int IJ_TO_POS [][] = {
114+ // (0,0) (0,1) (1,0) (1,1)
115+ {0 , 1 , 3 , 2 }, // canonical order
116+ {0 , 3 , 1 , 2 }, // axes swapped
117+ {2 , 3 , 1 , 0 }, // bits inverted
118+ {2 , 1 , 3 , 0 }, // swapped & inverted
119+ };
120+
121+ /**
122+ * Returns the order in which a specified subcell is visited by the Hilbert
123+ * curve. This is the inverse of {@link #posToIJ}.
124+ *
125+ * @param orientation the subcell orientation, in the range [0,3].
126+ * @param ijIndex the subcell index where
127+ * {@code 0->(0,0), 1->(0,1), 2->(1,0), 3->(1,1)}.
128+ * @return the position of the subcell in the Hilbert traversal, in the range
129+ * [0,3].
130+ * @throws IllegalArgumentException if either parameter is out of bounds.
131+ */
132+ public static final int ijToPos (int orientation , int ijIndex ) {
133+ Preconditions .checkArgument (0 <= orientation && orientation < 4 );
134+ Preconditions .checkArgument (0 <= ijIndex && ijIndex < 4 );
135+ return IJ_TO_POS [orientation ][ijIndex ];
136+ }
137+
91138 /**
92139 * Defines an area or a length cell metric.
93140 */
0 commit comments