Program: 99223
Project: 99223
Buggy source:
protected Vector getVisibleKeys(PGraphics pg){
  float minX=pg.screenX(0,0);
  float minY=pg.screenY(0,0);
  float maxX=pg.screenX(TILE_WIDTH,TILE_HEIGHT);
  float maxY=pg.screenY(TILE_WIDTH,TILE_HEIGHT);
  int zoomLevel=Map.getZoomLevelFromScale((float)innerScale);
  int cols=(int)Map.getScaleFromZoom(zoomLevel);
  int rows=(int)Map.getScaleFromZoom(zoomLevel);
  float screenMinX=0;
  float screenMinY=0;
  float screenMaxX=width - TILE_WIDTH;
  float screenMaxY=height - TILE_HEIGHT;
  if (minX > maxX) {
    float t=minX;
    minX=maxX;
    maxX=t;
  }
  if (minY > maxY) {
    float t=minY;
    minY=maxY;
    maxY=t;
  }
  int minCol=(int)PApplet.floor(cols * (screenMinX - minX) / (maxX - minX));
  int maxCol=(int)PApplet.ceil(cols * (screenMaxX - minX) / (maxX - minX));
  int minRow=(int)PApplet.floor(rows * (screenMinY - minY) / (maxY - minY));
  int maxRow=(int)PApplet.ceil(rows * (screenMaxY - minY) / (maxY - minY));
  minCol-=grid_padding;
  minRow-=grid_padding;
  maxCol+=grid_padding;
  maxRow+=grid_padding;
  minCol=PApplet.constrain(minCol,0,cols);
  maxCol=PApplet.constrain(maxCol,0,cols);
  minRow=PApplet.constrain(minRow,0,rows);
  maxRow=PApplet.constrain(maxRow,0,rows);
  Vector visibleKeys=new Vector();
  for (int col=minCol; col <= maxCol; col++) {
    for (int row=minRow; row <= maxRow; row++) {
      Coordinate coord=provider.sourceCoordinate(new Coordinate(row,col,zoomLevel));
      coord.roundValues();
      visibleKeys.add(coord);
      if (!images.containsKey(coord)) {
        grabTile(coord);
        boolean gotParent=false;
        for (int i=(int)coord.zoom; i > 0; i--) {
          Coordinate zoomed=coord.zoomTo(i).container();
          zoomed.roundValues();
          if (images.containsKey(zoomed)) {
            visibleKeys.add(zoomed);
            gotParent=true;
            break;
          }
        }
        if (!gotParent) {
          Coordinate zoomed=coord.zoomBy(1).container();
          Coordinate[] kids={zoomed,zoomed.right(),zoomed.down(),zoomed.right().down()};
          for (int i=0; i < kids.length; i++) {
            zoomed=kids[i];
            zoomed.row=PApplet.round(zoomed.row);
            zoomed.column=PApplet.round(zoomed.column);
            zoomed.zoom=PApplet.round(zoomed.zoom);
            if (images.containsKey(zoomed)) {
              visibleKeys.add(zoomed);
            }
          }
        }
      }
    }
  }
  Collections.sort(visibleKeys,zoomComparator);
  queue.retainAll(visibleKeys);
  queueSorter.setCenter(new Coordinate((minRow + maxRow) / 2.0f,(minCol + maxCol) / 2.0f,zoomLevel));
  Collections.sort(queue,queueSorter);
  processQueue();
  return visibleKeys;
}

Fixed version (ground truth):
protected Vector getVisibleKeys(PGraphics pg){
  int zoomLevel=Map.getZoomLevelFromScale((float)innerScale);
  float[] innerTL=getInnerObjectFromObjectPosition(0,0);
  float[] innerTR=getInnerObjectFromObjectPosition(getWidth(),0);
  float[] innerBR=getInnerObjectFromObjectPosition(getWidth(),getHeight());
  float[] innerBL=getInnerObjectFromObjectPosition(0,getHeight());
  Coordinate coordTL=getCoordinateFromInnerPosition(innerTL[0],innerTL[1]).zoomTo(zoomLevel);
  Coordinate coordTR=getCoordinateFromInnerPosition(innerTR[0],innerTR[1]).zoomTo(zoomLevel);
  Coordinate coordBR=getCoordinateFromInnerPosition(innerBR[0],innerBR[1]).zoomTo(zoomLevel);
  Coordinate coordBL=getCoordinateFromInnerPosition(innerBL[0],innerBL[1]).zoomTo(zoomLevel);
  int minCol=(int)PApplet.min(new float[]{coordTL.column,coordTR.column,coordBR.column,coordBL.column});
  int maxCol=(int)PApplet.max(new float[]{coordTL.column,coordTR.column,coordBR.column,coordBL.column});
  int minRow=(int)PApplet.min(new float[]{coordTL.row,coordTR.row,coordBR.row,coordBL.row});
  int maxRow=(int)PApplet.max(new float[]{coordTL.row,coordTR.row,coordBR.row,coordBL.row});
  minCol-=grid_padding;
  minRow-=grid_padding;
  maxCol+=grid_padding;
  maxRow+=grid_padding;
  int numberTiles=(int)Map.getScaleFromZoom(zoomLevel);
  minCol=PApplet.constrain(minCol,0,numberTiles);
  maxCol=PApplet.constrain(maxCol,0,numberTiles);
  minRow=PApplet.constrain(minRow,0,numberTiles);
  maxRow=PApplet.constrain(maxRow,0,numberTiles);
  Vector visibleKeys=new Vector();
  for (int col=minCol; col <= maxCol; col++) {
    for (int row=minRow; row <= maxRow; row++) {
      Coordinate coord=provider.sourceCoordinate(new Coordinate(row,col,zoomLevel));
      coord.roundValues();
      visibleKeys.add(coord);
      if (!images.containsKey(coord)) {
        grabTile(coord);
        boolean gotParent=false;
        for (int i=(int)coord.zoom; i > 0; i--) {
          Coordinate zoomed=coord.zoomTo(i).container();
          zoomed.roundValues();
          if (images.containsKey(zoomed)) {
            visibleKeys.add(zoomed);
            gotParent=true;
            break;
          }
        }
        if (!gotParent) {
          Coordinate zoomed=coord.zoomBy(1).container();
          Coordinate[] kids={zoomed,zoomed.right(),zoomed.down(),zoomed.right().down()};
          for (int i=0; i < kids.length; i++) {
            zoomed=kids[i];
            zoomed.row=PApplet.round(zoomed.row);
            zoomed.column=PApplet.round(zoomed.column);
            zoomed.zoom=PApplet.round(zoomed.zoom);
            if (images.containsKey(zoomed)) {
              visibleKeys.add(zoomed);
            }
          }
        }
      }
    }
  }
  Collections.sort(visibleKeys,zoomComparator);
  queue.retainAll(visibleKeys);
  queueSorter.setCenter(new Coordinate((minRow + maxRow) / 2.0f,(minCol + maxCol) / 2.0f,zoomLevel));
  Collections.sort(queue,queueSorter);
  processQueue();
  return visibleKeys;
}