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