@Override public void operate(GeoGrid src, GeoGrid dst, int startRow, int endRow) { final int cols = src.getCols(); final int rows = src.getRows(); final double cellSize = src.getCellSize(); final double gg = cellSize * cellSize; final int firstInteriorRow = Math.max(1, startRow); final int lastInteriorRow = Math.min(rows - 1, endRow); // top row if (startRow == 0) { for (int col = 0; col < cols; col++) { operateBorder(src, dst, col, 0, cellSize); } } // bottom row if (endRow == rows - 1) { for (int col = 0; col < cols; col++) { operateBorder(src, dst, col, rows - 1, cellSize); } } // left column for (int row = firstInteriorRow; row < lastInteriorRow; row++) { operateBorder(src, dst, 0, row, cellSize); } // right column for (int row = firstInteriorRow; row < lastInteriorRow; row++) { operateBorder(src, dst, cols - 1, row, cellSize); } // interior of grid float[][] srcGrid = src.getGrid(); float[][] dstGrid = dst.getGrid(); for (int row = firstInteriorRow; row < lastInteriorRow; row++) { for (int col = 1; col < cols - 1; col++) { final float z1 = srcGrid[row - 1][col - 1]; // top left final float z2 = srcGrid[row - 1][col]; // top final float z3 = srcGrid[row - 1][col + 1]; // top right final float z4 = srcGrid[row][col - 1]; // left final float z5 = srcGrid[row][col]; // center final float z6 = srcGrid[row][col + 1]; // right final float z7 = srcGrid[row + 1][col - 1]; // bottom left final float z8 = srcGrid[row + 1][col]; // bottom final float z9 = srcGrid[row + 1][col + 1]; // bottom right final double a = gg * ((z1 + z3 + z4 + z6 + z7 + z9) / 6 - (z2 + z5 + z8) / 3); final double b = gg * ((z1 + z2 + z3 + z7 + z8 + z9) / 6 - (z4 + z5 + z6) / 3); final double a_b = a - b; final double c = (z3 + z7 - z1 - z9) / 4 * gg; final double v = -a - b + Math.sqrt(a_b * a_b + c * c); dstGrid[row][col] = v < 0f ? 0f : (float) v; } } }
private void operateBorder(GeoGrid src, GeoGrid dst, int col, int row, double cellSize) { float[][] srcGrid = src.getGrid(); float[][] dstGrid = dst.getGrid(); final int cols = src.getCols(); final int rows = src.getRows(); final int rm = row - 1 < 0 ? 0 : row - 1; final int rp = row + 1 >= rows ? rows - 1 : row + 1; final int cm = col - 1 < 0 ? 0 : col - 1; final int cp = col + 1 >= cols ? cols - 1 : col + 1; final float z1 = srcGrid[rm][cm]; // top left final float z2 = srcGrid[rm][col]; // top final float z3 = srcGrid[rm][cp]; // top right final float z4 = srcGrid[row][cm]; // left final float z5 = srcGrid[row][col]; // center final float z6 = srcGrid[row][cp]; // right final float z7 = srcGrid[rp][cm]; // bottom left final float z8 = srcGrid[rp][col]; // bottom final float z9 = srcGrid[rp][cp]; // bottom right final double gg = cellSize * cellSize; final double a = gg * ((z1 + z3 + z4 + z6 + z7 + z9) / 6 - (z2 + z5 + z8) / 3); final double b = gg * ((z1 + z2 + z3 + z7 + z8 + z9) / 6 - (z4 + z5 + z6) / 3); final double a_b = a - b; final double c = (z3 + z7 - z1 - z9) / 4 * gg; final double v = -a - b + Math.sqrt(a_b * a_b + c * c); dstGrid[row][col] = v < 0f ? 0f : (float) v; }
public GeoPath traceSingleContourAtPoint(GeoGrid geoGrid, double x, double y) { this.flags = new boolean[geoGrid.getRows()][geoGrid.getCols()]; double cellSize = geoGrid.getCellSize(); double west = geoGrid.getWest(); double north = geoGrid.getNorth(); double level = geoGrid.getBicubicInterpol(x, y); int[] cell = new int[] {(int) ((x - west) / cellSize), (int) ((north - y) / cellSize)}; GeoPath geoPath = traceContour(geoGrid.getGrid(), cell, level, west, north, cellSize); return geoPath; }
private void contourLevel(GeoGrid geoGrid, double level, GeoSet levelGeoSet) { final int nbrCellsX = geoGrid.getCols() - 1; final int nbrCellsY = geoGrid.getRows() - 1; float[][] grid = geoGrid.getGrid(); double west = geoGrid.getWest(); double north = geoGrid.getNorth(); double cellSize = geoGrid.getCellSize(); for (int i = 0; i < this.flags.length; i++) { java.util.Arrays.fill(this.flags[i], false); } for (int y = 0; y < nbrCellsY; y++) { boolean[] flag_row = flags[y]; for (int x = 0; x < nbrCellsX; x++) { if (flag_row[x] == false) { traceContour(grid, new int[] {x, y}, level, west, north, cellSize, levelGeoSet); } } } }
public GeoObject operate(GeoGrid geoGrid, double firstContourLevel, double lastContourLevel) { flags = new boolean[geoGrid.getRows()][geoGrid.getCols()]; GeoSet geoSet = new GeoSet(); final int nlevels = (int) ((lastContourLevel - firstContourLevel) / interval) + 1; if (treatDegreeJump) { GeoSet levelGeoSet = new GeoSet(); this.contourLevel(geoGrid, 0.f, levelGeoSet); levelGeoSet.setName(Float.toString(0.f)); geoSet.add(levelGeoSet); } for (int i = 0; i < nlevels; ++i) { final double contourLevel = firstContourLevel + i * interval; GeoSet levelGeoSet = new GeoSet(); this.contourLevel(geoGrid, contourLevel, levelGeoSet); levelGeoSet.setName(Double.toString(contourLevel)); geoSet.add(levelGeoSet); } return geoSet; }