protected static void midpointDisplacement(final HeightField hf,
			final int L, final int MX, final int MY, int range,
			final float persist, final long seed) {
		/*
		 * NOTE: A is (x1, y1) B is (x2, y2) A,B,C,D are the original "corner"
		 * points
		 * 
		 * G
		 * 
		 * B D
		 * 
		 * H E I
		 * 
		 * A C
		 * 
		 * F
		 */

		Random r = new Random(seed);

		for (int y = 0; y < MY; y += L) {
			for (int x = 0; x < MX; x += L) {
				hf.set(x, y, r.nextInt(256));
			}
		}

		int step = L;
		int halfStep = L / 2;
		int x2, y2, midx, midy;

		while (step >= 1) {
			// Diamond step across entire array...
			for (int y1 = 0; y1 < MY; y1 += step) {
				for (int x1 = 0; x1 < MX; x1 += step) {
					x2 = x1 + step;
					y2 = y1 + step;
					midx = x1 + halfStep;
					midy = y1 + halfStep;

					final int sum = hf.get(x1, y1) + hf.get(x1, y2)
							+ hf.get(x2, y1) + hf.get(x2, y2);

					hf.set(midx, midy, sum / 4 + perturb(r, range));
				}
			}

			// Square step across entire array...
			for (int y1 = 0; y1 < MY; y1 += step) {
				for (int x1 = 0; x1 < MX; x1 += step) {
					x2 = x1 + step;
					y2 = y1 + step;
					midx = x1 + halfStep;
					midy = y1 + halfStep;

					/*
					 * x1 mx x2 G
					 * 
					 * B 4 D y2
					 * 
					 * H 1 E 2 I midy
					 * 
					 * A 3 C y1
					 * 
					 * F
					 */
					int A = hf.get(x1, y1);
					int B = hf.get(x1, y2);
					int C = hf.get(x2, y1);
					int D = hf.get(x2, y2);
					int E = hf.get(midx, midy);
					int F = hf.get(midx, y1 - halfStep);
					int G = hf.get(midx, y2 + halfStep);
					int H = hf.get(x1 - halfStep, midy);
					int I = hf.get(x2 + halfStep, midy);

					hf.set(x1, midy, (A + B + E + H) / 4); // 1
					hf.set(x2, midy, (C + D + E + I) / 4); // 2
					hf.set(midx, y1, (A + C + E + F) / 4); // 3
					hf.set(midx, y2, (B + D + E + G) / 4); // 4
				}
			}

			// Prepare for next iteration...
			range *= persist;
			step /= 2;
			halfStep /= 2;
		}
	}