uses sysutils, BMPImage, ucomplex, utils; type TArgs = record width: longint; // TryStrToInt wants longint height: longint; power: longint; zoom: extended; center_x: extended; center_y: extended; out_path: string; end; const save_path = './images/generated/'; const help_text = 'Usage: command '; {function f(x: integer): integer; begin f := round(2 * sin(x) + 3); end; function check_a(x: integer; y: integer): boolean; begin check_a := sqr(x - 50) + sqr(y - 50) - 6 <= 900; end; function fr(x: integer; c: integer): integer; begin fr := sqr(x) + c; end;} function fc(x: complex; c: complex; n: integer): complex; begin fc := complex_sum(x.power(n), c); end; function translate_point(p: Point2D; width: integer; height: integer): Point2D; var base_zoom: integer; begin base_zoom := round(width * 0.8) div 2; p.update((p.x - width / 2) / base_zoom, (p.y - height / 2) / base_zoom); translate_point := p; end; function multibrot_check(x: extended; y: extended; n: integer): integer; // f defined as f(x) = x^2 + c, where c (complex number) is a constant // point (x, y) is in Mandelbrot's set if f(f(...f(0))) converges, c = x + yi var i: integer; v, c: complex; begin i := 0; v.update(0, 0); while (i < 255) and (v.length() <= 2) do begin c.update(x, y); v := fc(v, c, n); inc(i); end; multibrot_check := i; end; procedure setDefaultArgs(var args: TArgs); begin with args do begin width := 512; height := 512; power := 2; zoom := 1; center_x := 0; center_y := 0; out_path := './images'; end; end; function getArgs(var args: TArgs): boolean; var error: boolean; begin error := false; if (ParamCount > 7) then begin error := true; end else begin if (ParamCount >= 1) then begin if (not TryStrToInt(ParamStr(1), args.width)) then error := true; end; if (ParamCount >= 2) then begin if (not TryStrToInt(ParamStr(2), args.height)) then error := true; end; if (ParamCount >= 3) then begin if (not TryStrToInt(ParamStr(3), args.power)) then error := true; end; if (ParamCount >= 4) then begin if (not TryStrToFloat(ParamStr(4), args.zoom)) then error := true; end; if (ParamCount >= 5) then begin if (not TryStrToFloat(ParamStr(5), args.center_x)) then error := true; end; if (ParamCount >= 6) then begin if (not TryStrToFloat(ParamStr(6), args.center_y)) then error := true; end; if (ParamCount = 7) then begin args.out_path := ParamStr(7); end; end; getArgs := not error; end; function generateMultibrot( width: integer; height: integer; power: longint; zoom: extended; center_x: extended; center_y: extended ): TPxData; var color: TColor; i, j, mb_out: integer; p: Point2D; palette: array[0..255] of TColor; px_data: TPxData; begin setLength(px_data, width, height); color.reset(); for i := 0 to 254 do begin palette[i].set_color(i, abs(64 - i), abs(128 - i)); end; palette[255].set_color(0, 0, 0); for i := 0 to width - 1 do begin for j := 0 to height - 1 do begin p.update(i, j); p := translate_point(p, width, height); p.x := (p.x / zoom) + center_x; p.y := (p.y / zoom) + center_y; color.reset(); if ((abs(p.x) < 0.000001) or (abs(p.y) < 0.000001)) then begin color.g := 255; end else begin mb_out := multibrot_check(p.x, p.y, power); color := palette[mb_out]; end; px_data[i][j] := color; end; end; generateMultibrot := px_data; end; var args: TArgs; img: TBMPImage; out_path, fname: string; px_data: TPxData; begin {img.init(); img.open('./images/k.bmp'); // draw sin for i := 0 to img.get_width() - 1 do begin color.set_color(255, 0, 0); img.pixel_data[i][f(i)] := color; end; // convert color for i := 0 to img.get_width() - 1 do begin for j := 0 to img.get_height() - 1 do begin color := img.pixel_data[i][j]; new_color.r := color.b; new_color.g := color.g; new_color.b := color.r; img.pixel_data[i][j] := new_color; end; end; img.set_width(400); img.set_height(400); img.save('./images/generated/k_generic.bmp', false); img.done();} setDefaultArgs(args); if (getArgs(args)) then begin px_data := generateMultibrot(args.width, args.height, args.power, args.zoom, args.center_x, args.center_y); img.init(px_data); fname := get_filename('mb' + IntToStr(args.power) + '_set', args.zoom, args.center_x, args.center_y); out_path := args.out_path + '/' + fname; img.save(out_path, false); img.done(); writeln(fname); {color.set_color(255, 255, 255); img.init(100, 100, color); color.set_color(0, 255, 0); for i := 0 to img.get_width() - 1 do begin for j := 0 to img.get_height() - 1 do begin if (check_a(i, j)) then begin img.pixel_data[i][j] := color; end; end; end; img.save('./images/generated/circle.bmp', false); img.done();} end else begin writeln(help_text); end; end.