X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Fthreedee%2FTerrainPatch.java;fp=tim%2Fprune%2Fthreedee%2FTerrainPatch.java;h=10f0b6ee1c4c1fb3492a20e9537950c5c92d13ba;hp=0000000000000000000000000000000000000000;hb=0a2480df5845e2d7190dfdec9b2653b1609e853d;hpb=2154b1969ac2995cca46546f217f53c066b0b749 diff --git a/tim/prune/threedee/TerrainPatch.java b/tim/prune/threedee/TerrainPatch.java new file mode 100644 index 0000000..10f0b6e --- /dev/null +++ b/tim/prune/threedee/TerrainPatch.java @@ -0,0 +1,116 @@ +package tim.prune.threedee; + +public class TerrainPatch +{ + private int _gridSize = 0; + private double[] _altitudes = null; + private int[] _tempDists = null; + + /** + * Constructor + * @param inGridSize size of grid edge + */ + public TerrainPatch(int inGridSize) + { + _gridSize = inGridSize; + int numNodes = inGridSize * inGridSize; + _altitudes = new double[numNodes]; + _tempDists = new int[numNodes]; + } + + /** + * Add an altitude interpolation to the mix + * @param inPointIndex point index to array + * @param inValue altitude value in metres + * @param inGapIndex index of point within gap, from 1 to gapLength-1 + * @param inGapLength length of gap, minimum 2 + */ + public void addAltitude(int inPointIndex, double inValue, int inGapIndex, int inGapLength) + { + final int dist = Math.min(inGapIndex, inGapLength-inGapIndex); + if (_tempDists[inPointIndex] == 0) + { + if (_altitudes[inPointIndex] > 0.0) System.err.println("Altitude shouldn't be 0 if dist is 0!"); + // first point + _altitudes[inPointIndex] = inValue; + _tempDists[inPointIndex] = dist; + } + else + { + // second point + final double firstValue = _altitudes[inPointIndex]; + final int firstDist = _tempDists[inPointIndex]; + final double firstWeight = dist * 1.0 / (dist + firstDist); + final double secondWeight= firstDist * 1.0 / (dist + firstDist); + _altitudes[inPointIndex] = firstWeight * firstValue + secondWeight * inValue; + _tempDists[inPointIndex] = 0; + } + } + + /** + * Smooth the patch to reduce blockiness + */ + public void smooth() + { + double[] altCopy = new double[_altitudes.length]; + for (int i=0; i<_gridSize; i++) + { + for (int j=0; j<_gridSize; j++) + { + if (hasAltitude(i, j) && hasAltitude(i-1, j) && hasAltitude(i+1, j) + && hasAltitude(i, j+1) && hasAltitude(i-1, j+1) && hasAltitude(i+1, j+1) + && hasAltitude(i, j-1) && hasAltitude(i-1, j-1) && hasAltitude(i+1, j-1)) + { + // got a 3x3 square, can do a blur + double alt = (getAltitude(i, j) + getAltitude(i-1, j) + getAltitude(i+1, j) + + getAltitude(i, j+1) + getAltitude(i-1, j+1) + getAltitude(i+1, j+1) + + getAltitude(i, j-1) + getAltitude(i-1, j-1) + getAltitude(i+1, j-1)) / 9.0; + altCopy[i * _gridSize + j] = alt; + } + } + } + // Copy results back + for (int k=0; k 0.0) + { + _altitudes[k] = altCopy[k]; + } + } + } + + /** + * @param inI first index + * @param inJ second index + * @return true if there is an altitude in the patch in this position + */ + private boolean hasAltitude(int inI, int inJ) + { + return inI >= 0 && inI < _gridSize && inJ >= 0 && inJ < _gridSize + && _altitudes[inI * _gridSize + inJ] > 0.0; + } + + /** + * @param inI first index + * @param inJ second index + * @return true if there is an altitude in the patch in this position + */ + private double getAltitude(int inI, int inJ) + { + if (inI >= 0 && inI < _gridSize && inJ >= 0 && inJ < _gridSize) + { + return _altitudes[inI * _gridSize + inJ]; + } + return 0.0; + } + + /** + * @param inPointIndex point index + * @return altitude value + */ + public double getAltitude(int inPointIndex) + { + if (_tempDists[inPointIndex] != 0) System.err.println("Dists should be 0 if we're retrieving!"); + return _altitudes[inPointIndex]; + } +}