Automatic Terrain Generation
08 Jan 2013
A set a tools for generating artificial terrain and other rough phenomena mapped over a 2D surface.
function [zm, xm, ym] = generate_brownian_mesh(n, zm)
% [zm, xm, ym] = generate_brownian_mesh(n, zm)
% Generate a mesh of points exhibiting "fractal Brownian motion", a random
% mesh that more-or-less looks like terrain. The output "height" mesh maps
% over [0, 0] to [1, 1] with 2^n+1 points along each axis for (2^n+1)^2
% total data points. This method is also known as the midpoint displacement
% n - Number of iterations
% zm - Initial heights
% zm - "z" data corresponding to mesh
% xm - "x" data corresponding to mesh
% ym - "y" data corresponding to mesh
% [hm, xm, ym] = generate_brownian_mesh(8);
% hm(hm < 0) = 0;
% surf(xm, ym, 0.1*hm);
% shading interp;
% caxis([0 0.25]);
% axis equal vis3d;
% colormap(getfield(load('cape', 'map'), 'map'));
% camlight headlight;
% lighting phong;
% This technique was first proposed by Benoit Mandelbrot for generating
% realistic looking landscapes ("Fractal landscape", Wikipedia).
% For an example, see terrain_generation_introduction.m or
% Tucker McClure
% Copyright 2012, The MathWorks, Inc.
% If no initial mesh is specified, create one randomly.
if nargin < 2
zm = randn(2, 2);
s = 1;
s = 1/(size(zm, 1) - 1);
% Make the initial x and y meshes.
[xm, ym] = meshgrid(0:s:1, 0:s:1);
% Refine for n iterations.
for k = 1:n
% Distance between neighboring components.
d = 0.5^k * s;
% Make new meshes.
[xm_new, ym_new] = meshgrid(0:d:1, 0:d:1);
% Interpolate and add random variation to the new mesh.
zm = interp2(xm, ym, zm, xm_new, ym_new) + d * randn(2^k/s + 1);
% What was old becomes new.
xm = xm_new;
ym = ym_new;