program LinearNoise96;
	uses
		simpleWindows, Cwindows, stringTools, IOTools, randomTools;
	const
		size = 39;{multiple of 3 for splines}
	type
		noiseArray = array[0..size, 0..size] of real;
	var
		noiseB, noiseR, noiseG: noiseArray;
		h, v: longint;							{pixel coordinates}
		divisor: longint;						{for spreading out the noise}
		x, y: real;								{x = h/divisor, y= v/divisor are sent to LinearNoise function}
		factorR, factorG, factorB, factor: real;{to set the proportions of Red, Green, Blue}
		myColor: rgbColor;						{The color that the pixel is set to}
		start: integer;							{for starting scale}
		choice: integer;						{ which procedure to call}
		normalize: boolean;
	procedure openWindows;
	begin
{ set defaults for drawing window - see simpleCwindows }
		with Coptions do
			begin
				title := '';
				framewidth := 3;
				framecolor := white;
				fieldcolor := black;
			end;
		hideall;
		macii_minitext;
		miniCdraw;
		writeln('Uniform Linear Noise Samples');
		random_seed(tickCount);
	end;
	procedure setNoises;
		var
			i, j, k: integer;
			sum: real;
	begin
		for i := 0 to size - 1 do
			for j := 0 to size - 1 do
				begin
					noiseR[i, j] := random_real(0, 1);	{set all but last row and column to random reals between 0 and 1}
					noiseG[i, j] := random_real(0, 1);
					noiseB[i, j] := random_real(0, 1);
				end;
		for j := 1 to size - 1 do
			begin
				noiseR[size, j] := noiseR[0, j];		{set the last row and column to match the first row and column}
				noiseR[j, size] := noiseR[j, 0];
				noiseG[size, j] := noiseG[0, j];
				noiseG[j, size] := noiseG[j, 0];
				noiseB[size, j] := noiseB[0, j];
				noiseB[j, size] := noiseB[j, 0];
			end;
		noiseR[size, size] := noiseR[0, 0];			{set the last corner to complete the wrap}
		noiseG[size, size] := noiseG[0, 0];
		noiseB[size, size] := noiseB[0, 0];
	end;
	function linearNoise (u, v: real; var noise: noiseArray): real;
		var
			iu, iv, ip, iq: integer;
			du, dv, bot, top: real;
	begin
		iu := trunc(u);
		iv := trunc(v);
		du := u - iu;
		dv := v - iv;
		iu := iu mod size;
		iv := iv mod size;
		ip := (iu + 1);
		iq := (iv + 1);
		bot := noise[iu, iv] + du * (noise[ip, iv] - noise[iu, iv]);
		top := noise[iu, iq] + du * (noise[ip, iq] - noise[iu, iq]);
		linearNoise := bot + dv * (top - bot);
	end;
	function Lturbulence (u, v: real; var noise: noiseArray): real;
		var
			t, scale: real;
	begin
		scale := start;
		t := 0;
		while scale >= 1 / divisor do {1 / divisor}
			begin
				t := t + linearNoise(u / scale, v / scale, noise) * scale;
				scale := scale / 2;
			end;
		if normalize then {normalized turbulence}
			t := t / 2 / start;
		Lturbulence := t;
	end;
	function marble (x, y: real; var noise: noiseArray): real;
		var
			marb: real;
	begin
		marble := abs(sin(x + Lturbulence(x, y, noise)));
	end;
	function cloud (x, y: real; var noise: noiseArray): real;
	begin
		cloud := sin(x + Lturbulence(x, y, noise));
	end;
	procedure noiseColor (x, y: real);
	begin
		factorR := linearNoise(x, y, noiseR);
		factorG := linearNoise(x, y, noiseG);
		factorB := linearNoise(x, y, noiseB);
		with myColor do
			begin
				red := round(2 * factorR * maxint);
				green := round(2 * factorG * maxint);
				blue := round(2 * factorB * maxint);
			end;
	end;
	procedure turbulenceColor (x, y: real);
	begin
		factorR := Lturbulence(x, y, noiseR);
		factorG := Lturbulence(x, y, noiseG);
		factorB := Lturbulence(x, y, noiseB);
		with myColor do
			begin
				red := round(2 * factorR * maxint);
				green := round(2 * factorG * maxint);
				blue := round(2 * factorB * maxint);
			end;
	end;
	procedure marbleColor (x, y: real);
	begin
{    factorR := marble(x, y, noiseR);	}
{square factorR to make a narrower band of yellow where red adds to green}
{    factorR := factorR * factorR;}
		factorG := sqrt(marble(x, y, noiseG));{take the square root to fatten the green bands, leaving thin blue veins}
		with myColor do
			begin
				red := 0;{trunc(factorR * maxint);}
				green := trunc(2 * factorG * maxint);
				blue := trunc(maxint);
			end;
	end;
	procedure cloudColor (x, y: real);
	begin
		factorR := abs(cloud(x, y, noiseR));
		factorG := abs(cloud(y, x, noiseG));	{note that x and y are flipped; fuzziness in two directions}
		factor := abs(factorR + factorG) / 2;	{factor scales from blue to white}
		with myColor do
			begin
				red := maxint + trunc(factor * maxint);
				green := maxint + trunc(factor * maxint);
				blue := maxint + trunc((1 - factor / 2) * maxint);
			end;
	end;
{------main----------------------------------------------------------------------}
begin
	openWindows;
	setNoises;
	divisor := 1;
	start := 1;
	choice := 2;
	repeat
		start := request_integer('Enter scale = ', start);
		divisor := request_integer('Enter divisor = ', divisor);
		writeln('Choose one: 1. noise');
		writeln('            2. turbulence');
		writeln('            3. marble');
		writeln('            4. clouds');
		choice := request_integer('Enter choice = ', choice);
		if (choice = 2) or (choice = 3) or (choice = 4) then
			normalize := confirm('Normalize turbulence? ', false);
		with CdrawingRect do
			begin
				for v := 0 to bottom do
					for h := 0 to right do
						begin
							x := h / divisor;
							y := v / divisor;
							case choice of
								1: 
									noiseColor(x, y);
								2: 
									turbulenceColor(x, y);
								3: 
									marbleColor(x, y);
								4: 
									cloudColor(x, y);
								otherwise
									;
							end; {case}
							setCPixel(h, v, myColor);
						end;
			end;
	until not confirm('Continue? ', true);
	readln;
end.
Harriet J. Fell
Last Updated: December 20, 2005, 10:56 a.m.
The URL for this document is:
http://www.ccs.neu.edu/home/fell/COM3370/noiseCode.html