unit fractal; interface type pbyte = ^byte; tFracdata = record area_left, area_right, area_top, area_bottom : real; max_iter : integer; super_factor : integer; field_width, field_height : integer; arr_width, arr_height : integer; end; var default_data : tFracdata; frac_data : tFracdata; procedure calc_line(y : integer); procedure plot_field(pb : pbyte; rowstride : integer); procedure set_frac_data(fd : tFracData); implementation uses colour; const DEF_MAX_ITER = 50; DEF_FIELD_WIDTH = 640; DEF_FIELD_HEIGHT = 480; DEF_AREA_LEFT = -2.6; DEF_AREA_RIGHT = 1; DEF_AREA_TOP = 1.35; DEF_AREA_BOTTOM = -1.35; DEF_SUPER_FACTOR = 1; type line = array of integer; var field : array of line; procedure calc_line(y : integer); var x : integer; cx, cy, zx, zy, zxn, zyn : real; step_x, step_y : real; i : integer; begin step_x := (frac_data.area_right - frac_data.area_left) / frac_data.arr_width; step_y := (frac_data.area_top - frac_data.area_bottom) / frac_data.arr_height; cy := frac_data.area_bottom + y * step_y; cx := frac_data.area_left; for x := 0 to frac_data.arr_width - 1 do begin zx := 0; zy := 0; i := 0; while (zx * zx + zy * zy <= 4) and (i <= frac_data.max_iter) do begin zxn := zx * zx - zy * zy + cx; zyn := 2 * zx * zy + cy; zx := zxn; zy := zyn; inc(i); end; if i > frac_data.max_iter then field[y][x] := -1 else field[y][x] := i; cx := cx + step_x; end; end; procedure plot_field(pb : pbyte; rowstride : integer); var x, y : integer; long_r, long_g, long_b : integer; ax, ay, sub_x, sub_y : integer; i : integer; colour : HsvColour; rgb : RgbColour; begin rowstride := rowstride - frac_data.field_width * 3; for y := 0 to frac_data.field_height - 1 do begin for x := 0 to frac_data.field_width - 1 do begin ax := x * frac_data.super_factor; ay := y * frac_data.super_factor; long_r := 0; long_g := 0; long_b := 0; for sub_x := ax to ax + frac_data.super_factor - 1 do for sub_y := ay to ay + frac_data.super_factor - 1 do begin i := field[sub_y][sub_x]; with colour do begin if i > -1 then begin h := i mod 255; v := 255; end else begin h := 0; v := 0; end; s := 255; end; rgb := hsv_to_rgb(colour); long_r := long_r + rgb.r; long_g := long_g + rgb.g; long_b := long_b + rgb.b; end; with rgb do begin r := long_r div (frac_data.super_factor * frac_data.super_factor); g := long_g div (frac_data.super_factor * frac_data.super_factor); b := long_b div (frac_data.super_factor * frac_data.super_factor); end; with rgb do begin pb^ := r; inc(pb); pb^ := g; inc(pb); pb^ := b; inc(pb); end; end; pb := pb + rowstride; end; end; procedure set_frac_data(fd : tFracData); var i : integer; begin frac_data := fd; with frac_data do begin arr_width := field_width * super_factor; arr_height := field_height * super_factor; setlength(field, arr_height); for i := 0 to arr_height - 1 do setlength(field[i], arr_width); end; end; var i : integer; begin with default_data do begin arr_width := DEF_FIELD_WIDTH * DEF_SUPER_FACTOR; arr_height := DEF_FIELD_HEIGHT * DEF_SUPER_FACTOR; field_width := DEF_FIELD_WIDTH; field_height := DEF_FIELD_HEIGHT; area_left := DEF_AREA_LEFT; area_right := DEF_AREA_RIGHT; area_top := DEF_AREA_TOP; area_bottom := DEF_AREA_BOTTOM; max_iter := DEF_MAX_ITER; super_factor := DEF_SUPER_FACTOR; setlength(field, arr_height); for i := 0 to arr_height - 1 do setlength(field[i], arr_width); end; end.