Quote Originally Posted by alexione View Post
Here's some code which uses virtual functions (as JSoftware) suggested. Most of the code should compile (I didn't test it). Let me know if you need more detailed explanation.

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;
       &nbspATA: 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   &nbspATA := 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;
Wow! Thanks alexione...that is much more than I expected from anyone to do for me

I will see what I can do with the code.

Thanks again so much mate

cheers,
Paul