public void setField(Object field) {
   super.setField(field);
   ObjectGrid2D og = (ObjectGrid2D) field;
   grid = new DoubleGrid2D(og.getWidth(), og.getHeight());
   valueGridPortrayal.setField(grid);
 }
  public void draw(Object object, Graphics2D graphics, DrawInfo2D info) {
    if (field == null) return;

    ObjectGrid2D ogrid = (ObjectGrid2D) field;

    // compute what area to do (as usual)

    final int maxX = ogrid.getWidth();
    final int maxY = ogrid.getHeight();
    if (maxX == 0 || maxY == 0) return;

    final double divideByX =
        ((maxX % 2 == 0) ? (3.0 * maxX / 2.0 + 0.5) : (3.0 * maxX / 2.0 + 2.0));
    final double divideByY = (1.0 + 2.0 * maxY);

    final double xScale = info.draw.width / divideByX;
    final double yScale = info.draw.height / divideByY;
    int startx = (int) (((info.clip.x - info.draw.x) / xScale - 0.5) / 1.5) - 2;
    int starty = (int) ((info.clip.y - info.draw.y) / (yScale * 2.0)) - 2;
    int endx = /*startx +*/
        (int) (((info.clip.x - info.draw.x + info.clip.width) / xScale - 0.5) / 1.5)
            + 4; // with rounding, width be as much as 1 off
    int endy = /*starty +*/
        (int) ((info.clip.y - info.draw.y + info.clip.height) / (yScale * 2.0))
            + 4; // with rounding, height be as much as 1 off

    //        double precomputedWidth = -1;  // see discussion further below
    //        double precomputedHeight = -1;  // see discussion further below

    //
    //
    // CAUTION!
    //
    // At some point we should triple check the math for rounding such
    // that the margins are drawn properly
    //
    //

    // Horizontal hexagons are staggered.  This complicates computations.  Thus
    // if  you have a M x N grid scaled to SCALE, then
    // your height is (N + 0.5) * SCALE
    // and your width is ((M - 1) * (3/4) + 1) * HEXAGONAL_RATIO * SCALE
    // we invert these calculations here to compute the rough width and height
    // for the newinfo here.  Additionally, because the original screen sizes were likely
    // converted from floats to ints, there's a round down there, so we round up to
    // compensate.  This usually results in nice circles.

    if (endx > maxX) endx = maxX;
    if (endy > maxY) endy = maxY;
    if (startx < 0) startx = 0;
    if (starty < 0) starty = 0;

    // convert the object grid into a double grid
    for (int x = startx; x < endx; x++) {
      double[] gridx = grid.field[x];
      Object[] ogridx = ogrid.field[x];
      for (int y = starty; y < endy; y++) gridx[y] = doubleValue(ogridx[y]);
    }

    // now ask the ValueGridPortrayal to draw it!
    valueGridPortrayal.draw(object /* doesn't matter */, graphics, info);
  }