cdm/src/main/java/ucar/nc2/dataset/CoordinateAxis2D.java
static public ArrayDouble.D2 makeEdges(ArrayDouble.D2 midpoints) {
    int[] shape = midpoints.getShape();
    int ny = shape[0];
    int nx = shape[1];
    ArrayDouble.D2 edge = new ArrayDouble.D2(ny + 1, nx + 1);

    for (int y = 0; y < ny - 1; y++) {
      for (int x = 0; x < nx - 1; x++) {
        // the interior edges are the average of the 4 surrounding midpoints
        double xval = (midpoints.get(y, x) + midpoints.get(y, x + 1) + midpoints.get(y + 1, x) + midpoints.get(y + 1, x + 1)) / 4;
        edge.set(y + 1, x + 1, xval);
      }
      // extrapolate to exterior points
      edge.set(y + 1, 0, edge.get(y + 1, 1) - (edge.get(y + 1, 2) - edge.get(y + 1, 1)));
      edge.set(y + 1, nx, edge.get(y + 1, nx - 1) + (edge.get(y + 1, nx - 1) - edge.get(y + 1, nx - 2)));
    }

    // extrapolate to the first and last row
    for (int x = 0; x < nx + 1; x++) {
      edge.set(0, x, edge.get(1, x) - (edge.get(2, x) - edge.get(1, x)));
      edge.set(ny, x, edge.get(ny - 1, x) + (edge.get(ny - 1, x) - edge.get(ny - 2, x)));
    }

    return edge;
  }
static public ArrayDouble.D2 makeEdges(ArrayDouble.D2 midpoints) {
    int[] shape = midpoints.getShape();
    int ny = shape[0];
    int nx = shape[1];
    ArrayDouble.D2 edge = new ArrayDouble.D2(ny + 1, nx + 1);

    for (int y = 0; y < ny - 1; y++) {
      for (int x = 0; x < nx - 1; x++) {
        // the interior edges are the average of the 4 surrounding midpoints
        double xval = (midpoints.get(y, x) + midpoints.get(y, x + 1) + midpoints.get(y + 1, x) + midpoints.get(y + 1, x + 1)) / 4;
        edge.set(y + 1, x + 1, xval);
      }
      // extrapolate to exterior points
      edge.set(y + 1, 0, edge.get(y + 1, 1) - (edge.get(y + 1, 2) - edge.get(y + 1, 1)));
      edge.set(y + 1, nx, edge.get(y + 1, nx - 1) + (edge.get(y + 1, nx - 1) - edge.get(y + 1, nx - 2)));
    }

    // extrapolate to the first and last row
    for (int x = 0; x < nx + 1; x++) {
      edge.set(0, x, edge.get(1, x) - (edge.get(2, x) - edge.get(1, x)));
      edge.set(ny, x, edge.get(ny - 1, x) + (edge.get(ny - 1, x) - edge.get(ny - 2, x)));
    }

    return edge;
  }
Normal case: do something reasonable in deciding on the edges when we have the midpoints of a 2D coordinate.

@param midpoints values of midpoints with shape (ny, nx)
@return values of edges with shape (ny+1, nx+1)