Fix an off-by-one error.

These variables were meant to represent the (x,y) coordinate of the
last pixel of the grid, to avoid going one pixel too far. But the last
pixel of the grid, of course, has coord (width - 1, height - 1).

This bug only ever happens in a rare case because to reproduce,
it needs the right (resp. bottom) coordinate of the rightmost
(resp. bottommost) plus the threshold plus half the grid width
(resp. height) to be exactly the number of pixels of the grid,
which is pretty unlikely... unless there are more tiles in the
grid than pixels on the screen, in which case the grid width is
1 and this becomes likely.

This fixes the fencepost error and renames the variables to
clarify their meaning.

Bug: 10537485
Change-Id: Iecfe2c0f29ee17776ee2cceaa4b1db722276b1f3
main
Jean Chalard 2013-09-19 13:43:09 +09:00
parent 8678062853
commit a7d0ab80a0
1 changed files with 5 additions and 7 deletions

View File

@ -245,8 +245,8 @@ public class ProximityInfo {
final int threshold = (int) (defaultWidth * SEARCH_DISTANCE); final int threshold = (int) (defaultWidth * SEARCH_DISTANCE);
final int thresholdSquared = threshold * threshold; final int thresholdSquared = threshold * threshold;
// Round-up so we don't have any pixels outside the grid // Round-up so we don't have any pixels outside the grid
final int fullGridWidth = mGridWidth * mCellWidth; final int lastPixelXCoordinate = mGridWidth * mCellWidth - 1;
final int fullGridHeight = mGridHeight * mCellHeight; final int lastPixelYCoordinate = mGridHeight * mCellHeight - 1;
// For large layouts, 'neighborsFlatBuffer' is about 80k of memory: gridSize is usually 512, // For large layouts, 'neighborsFlatBuffer' is about 80k of memory: gridSize is usually 512,
// keycount is about 40 and a pointer to a Key is 4 bytes. This contains, for each cell, // keycount is about 40 and a pointer to a Key is 4 bytes. This contains, for each cell,
@ -329,22 +329,20 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight; final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight;
final int yStart = Math.max(halfCellHeight, final int yStart = Math.max(halfCellHeight,
yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight)); yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight));
final int yEnd = Math.min(fullGridHeight, keyY + key.getHeight() + threshold); final int yEnd = Math.min(lastPixelYCoordinate, keyY + key.getHeight() + threshold);
final int leftPixelWithinThreshold = keyX - threshold; final int leftPixelWithinThreshold = keyX - threshold;
final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth; final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth;
final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth; final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth;
final int xStart = Math.max(halfCellWidth, final int xStart = Math.max(halfCellWidth,
xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth)); xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth));
final int xEnd = Math.min(fullGridWidth, keyX + key.getWidth() + threshold); final int xEnd = Math.min(lastPixelXCoordinate, keyX + key.getWidth() + threshold);
int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth); int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth);
for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) { for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) {
int index = baseIndexOfCurrentRow; int index = baseIndexOfCurrentRow;
for (int centerX = xStart; centerX <= xEnd; centerX += mCellWidth) { for (int centerX = xStart; centerX <= xEnd; centerX += mCellWidth) {
// TODO: Remove "index < neighborCountPerCell.length" below. if (key.squaredDistanceToEdge(centerX, centerY) < thresholdSquared) {
if (index < neighborCountPerCell.length
&& key.squaredDistanceToEdge(centerX, centerY) < thresholdSquared) {
neighborsFlatBuffer[index * keyCount + neighborCountPerCell[index]] = key; neighborsFlatBuffer[index * keyCount + neighborCountPerCell[index]] = key;
++neighborCountPerCell[index]; ++neighborCountPerCell[index];
} }