Code:
/*
def linear_gradient(start_value, stop_value, start_offset=0.0, stop_offset=1.0):
return lambda offset: (start_value + ((offset - start_offset) / (stop_offset - start_offset) * (stop_value - start_value))) / 255.0
*/
type
Tabstract_linear_gradient_function = class
function execute(offset: Single): Single; virtual; abstract;
end;
Tlinear_gradient_function = class(Tabstract_linear_gradient_function)
start_value: Single;
stop_value: Single;
start_offset: Single;
stop_offset: Single;
constructor Create(start_v, stop_v, start_o, stop_o: Single); override;
function execute(offset: Single): Single; override;
end;
constructor Tlinear_gradient_function.Create(start_v, stop_v, start_o, stop_o: Single);
begin
start_value := start_v;
stop_value := stop_v;
start_offset := start_o;
stop_offset := stop_o;
end;
funciton Tlinear_gradient_function.execute(offset: Single): Single;
begin
Result := (start_value + ((offset - start_offset) / (stop_offset - start_offset) * (stop_value - start_value))) / 255.0;
end;
/*
def RADIAL(center_x, center_y):
return lambda x, y: (x - center_x) ** 2 + (y - center_y) ** 2
*/
type
Tvalue_func = class
function execute(x, y: Single): Single; virtual; abstract;
end;
type
TRADIAL_value_func = class(Tvalue_func)
center_x: Single;
center_y: Single;
constructor Create(cx, cy: Single); override;
function execute(x, y: Single): Single; override;
end;
constructor TRADIAL_value_func.Create(cx, cy: Single);
begin
center_x := cx;
center_y := cy;
end;
function TRADIAL_value_func.execute(x, y: Single): Single;
begin
Result := Sqr(x - center_x) + Sqr(y - center_y);
end;
/*
def GAUSSIAN(sigma):
def add_noise(r, g, b):
d = random.gauss(0, sigma)
return r + d, g + d, b + d
return add_noise
*/
type
TRGB = record
r, g, b: Single;
end;
Tnoise_func = class
function execute(const rgb: TRGB): TRGB; virtual; abstract;
end;
TGAUSSIAN_noise_func = class(Tnoise_func)
sigma: Single;
constructor Create;
function execute(const rgb: TRGB): TRGB; override;
end;
constructor TGAUSSIAN_noise_func.Create;
begin
end;
function TGAUSSIAN_noise_func.execute(const rgb: TRGB): TRGB;
var
d: Single;
begin
d := RandomGauss(0, sigma);
Result.r := rgb.r + d;
Result.g := rgb.g + d;
Result.b := rgb.b + d;
end;
/*
def gradient(value_func, noise_func, DATA):
def gradient_function(x, y):
initial_offset = 0.0
v = value_func(x, y)
for offset, start, end in DATA:
if v < offset:
r = linear_gradient(start[0], end[0], initial_offset, offset)(v)
g = linear_gradient(start[1], end[1], initial_offset, offset)(v)
b = linear_gradient(start[2], end[2], initial_offset, offset)(v)
return noise_func(r, g, b)
initial_offset = offset
return noise_func(end[0] / 255.0, end[1] / 255.0, end[2] / 255.0)
return gradient_function
*/
type
TData = record
_offset: Single;
_start: array [0..2] of Single;
_end: array [0..2] of Single;
end;
Tgradient_function = class
value_func: Tvalue_func;
noise_func: Tnoise_func;
 ATA: array of TData;
constructor Create(const vf: Tvalue_func; const nf: Tnoise_function; const d: array of TData);
function execute(x, y: Single): TRGB;
end;
constructor Create(const vf: Tvalue_func; const nf: Tnoise_function; const d: array of TData);
begin
value_func := vf;
noise_func := nf;
0  ATA := d;
end;
function Tgradient_function.execute(x, y: Single): TRGB;
var
initial_offset: Single;
v: Single;
i: Integer;
rgb: TRGB;
lg: Tabstract_linear_gradient_function;
begin
initial_offset := 0.0;
v := value_func.execute(x, y);
for i := 0 to Length(DATA) - 1 do
begin
if v < DATA[i]._offset then
begin
lg := Tlinear_gradient_function.Create(DATA[i]._start[0], DATA[i]._end[0], initial_offset, DATA[i]._offset);
rgb.r := lg.execute(v);
lg.Free;
lg := Tlinear_gradient_function.Create(DATA[i]._start[1], DATA[i]._end[1], initial_offset, DATA[i]._offset);
rgb.g := lg.execute(v);
lg.Free;
lg := Tlinear_gradient_function.Create(DATA[i]._start[2], DATA[i]._end[2], initial_offset, DATA[i]._offset);
rgb.b := lg.execute(v);
lg.Free;
Result := noise_func.execute(rgb);
Exit;
end;
initial_offset:= DATA[i]._offset;
end;
rgb.r := DATA[Length(DATA) - 1]._end[0] / 255.0;
rgb.g := DATA[Length(DATA) - 1]._end[1] / 255.0;
rgb.b := DATA[Length(DATA) - 1]._end[2] / 255.0;
Result := noise_func(rgb);
end;
/*
write_png("example11.png", 480, 100,
gradient(RADIAL(0.5, 0.0), GAUSSIAN(0.01),
[(0.8, (0x22, 0x22, 0x22), (0x00, 0x00, 0x00))]
))
*/
procedure main;
const
d: TData = (_offset: 0.8; _start: ($22, $22, $22); _end: ($00, $00, $00));
var
vf: Tvalue_func;
nf: Tnoise_func;
gf: Tgradient_function;
begin
vf := TRADIAL_value_func.Create(0.5, 0.0);
nf := TGAUSSIAN_noise_func(0.01);
gf := Tgradient_function(vf, nf, d);
write_png('example11.png', 480, 100, gf);
gf.Free;
vf.Free;
nf.Free;
end;
Bookmarks