Skip to content

Commit 89b8770

Browse files
hagbardMichael Bolin
authored andcommitted
Made 'constant' classes fully immutable by either removing or wrapping final
static arrays. The IJ_TO_POS array was never being called so for now I removed it. We can trivially add it back (with appropriate lookup function) if we need it later. The other arrays were wrapped and given (hopefully) better JavaDoc. ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=25078833
1 parent 9d370a8 commit 89b8770

6 files changed

Lines changed: 89 additions & 56 deletions

File tree

src/com/google/common/geometry/S2.java

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/

src/com/google/common/geometry/S2Cell.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ public boolean subdivide(S2Cell children[]) {
144144
S2Cell child = children[pos];
145145
child.face = face;
146146
child.level = (byte) (level + 1);
147-
child.orientation = (byte) (orientation ^ S2.POS_TO_ORIENTATION[pos]);
147+
child.orientation = (byte) (orientation ^ S2.posToOrientation(pos));
148148
child.cellId = id;
149-
int ij = S2.POS_TO_IJ[orientation][pos];
149+
int ij = S2.posToIJ(orientation, pos);
150150
for (int d = 0; d < 2; ++d) {
151151
// The dimension 0 index (i/u) is in bit 1 of ij.
152152
int m = 1 - ((ij >> (1 - d)) & 1);

src/com/google/common/geometry/S2CellId.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -944,15 +944,13 @@ private static void initLookupCell(int level, int i, int j,
944944
i <<= 1;
945945
j <<= 1;
946946
pos <<= 2;
947-
int[] r = S2.POS_TO_IJ[orientation];
948-
initLookupCell(level, i + (r[0] >>> 1), j + (r[0] & 1), origOrientation,
949-
pos, orientation ^ S2.POS_TO_ORIENTATION[0]);
950-
initLookupCell(level, i + (r[1] >>> 1), j + (r[1] & 1), origOrientation,
951-
pos + 1, orientation ^ S2.POS_TO_ORIENTATION[1]);
952-
initLookupCell(level, i + (r[2] >>> 1), j + (r[2] & 1), origOrientation,
953-
pos + 2, orientation ^ S2.POS_TO_ORIENTATION[2]);
954-
initLookupCell(level, i + (r[3] >>> 1), j + (r[3] & 1), origOrientation,
955-
pos + 3, orientation ^ S2.POS_TO_ORIENTATION[3]);
947+
// Initialize each sub-cell recursively.
948+
for (int subPos = 0; subPos < 4; subPos++) {
949+
int ij = S2.posToIJ(orientation, subPos);
950+
int orientationMask = S2.posToOrientation(subPos);
951+
initLookupCell(level, i + (ij >>> 1), j + (ij & 1), origOrientation,
952+
pos + subPos, orientation ^ orientationMask);
953+
}
956954
}
957955
}
958956

src/com/google/common/geometry/S2Projections.java

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -214,25 +214,10 @@ public enum Projections {
214214
S2_PROJECTION == Projections.S2_QUADRATIC_PROJECTION ? 1.44261527445268292 : // 1.443
215215
0;
216216

217-
218-
public static final double MAX_DIAG_ASPECT = Math.sqrt(3); // 1.732
219217
// This is the maximum diagonal aspect ratio over all cells at any level,
220218
// where the diagonal aspect ratio of a cell is defined as the ratio of its
221219
// longest diagonal length to its shortest diagonal length.
222-
223-
224-
// IJ_TO_POS[orientation][ij] -> pos
225-
//
226-
// Given a cell orientation and the (i,j)-index of a subcell (0=(0,0),
227-
// 1=(0,1), 2=(1,0), 3=(1,1)), return the order in which this subcell is
228-
// visited by the Hilbert curve (a position in the range [0..3]).
229-
public static final int IJ_TO_POS[][] = {
230-
// (0,0) (0,1) (1,0) (1,1)
231-
{0, 1, 3, 2}, // canonical order
232-
{0, 3, 1, 2}, // axes swapped
233-
{2, 3, 1, 0}, // bits inverted
234-
{2, 1, 3, 0}, // swapped & inverted
235-
};
220+
public static final double MAX_DIAG_ASPECT = Math.sqrt(3); // 1.732
236221

237222
public static double stToUV(double s) {
238223
switch (S2_PROJECTION) {

tests/com/google/common/geometry/S2CellIdTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private void expandCell(
144144
MutableInteger childOrientation = new MutableInteger(0);
145145
assertEquals(child.toFaceIJOrientation(i, j, childOrientation), face);
146146
assertEquals(
147-
childOrientation.intValue(), orientation.intValue() ^ S2.POS_TO_ORIENTATION[pos]);
147+
childOrientation.intValue(), orientation.intValue() ^ S2.posToOrientation(pos));
148148

149149
parentMap.put(child, parent);
150150
expandCell(child, cells, parentMap);

tests/com/google/common/geometry/S2Test.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,33 @@ public strictfp class S2Test extends GeometryTestCase {
2121

2222
private static Logger logger = Logger.getLogger(S2Test.class.getName());
2323

24-
static int swapAxes(int ij) {
24+
// Test helper methods for testing the traversal order.
25+
private static int swapAxes(int ij) {
2526
return ((ij >> 1) & 1) + ((ij & 1) << 1);
2627
}
2728

28-
static int invertBits(int ij) {
29+
private static int invertBits(int ij) {
2930
return ij ^ 3;
3031
}
3132

3233
public void testTraversalOrder() {
3334
for (int r = 0; r < 4; ++r) {
3435
for (int i = 0; i < 4; ++i) {
3536
// Check consistency with respect to swapping axes.
36-
assertEquals(
37-
S2Projections.IJ_TO_POS[r][i], S2Projections.IJ_TO_POS[r ^ S2.SWAP_MASK][swapAxes(i)]);
38-
assertEquals(S2.POS_TO_IJ[r][i], swapAxes(S2.POS_TO_IJ[r ^ S2.SWAP_MASK][i]));
37+
assertEquals(S2.ijToPos(r, i),
38+
S2.ijToPos(r ^ S2.SWAP_MASK, swapAxes(i)));
39+
assertEquals(S2.posToIJ(r, i),
40+
swapAxes(S2.posToIJ(r ^ S2.SWAP_MASK, i)));
3941

4042
// Check consistency with respect to reversing axis directions.
41-
assertEquals(S2Projections.IJ_TO_POS[r][i],
42-
S2Projections.IJ_TO_POS[r ^ S2.INVERT_MASK][invertBits(i)]);
43-
assertEquals(S2.POS_TO_IJ[r][i], invertBits(S2.POS_TO_IJ[r ^ S2.INVERT_MASK][i]));
43+
assertEquals(S2.ijToPos(r, i),
44+
S2.ijToPos(r ^ S2.INVERT_MASK, invertBits(i)));
45+
assertEquals(S2.posToIJ(r, i),
46+
invertBits(S2.posToIJ(r ^ S2.INVERT_MASK, i)));
4447

4548
// Check that the two tables are inverses of each other.
46-
assertEquals(S2Projections.IJ_TO_POS[r][S2.POS_TO_IJ[r][i]], i);
47-
assertEquals(S2.POS_TO_IJ[r][S2Projections.IJ_TO_POS[r][i]], i);
49+
assertEquals(S2.ijToPos(r, S2.posToIJ(r, i)), i);
50+
assertEquals(S2.posToIJ(r, S2.ijToPos(r, i)), i);
4851
}
4952
}
5053
}

0 commit comments

Comments
 (0)