From 1f4577657e65d97dfd8cc121514534f0a45e0b50 Mon Sep 17 00:00:00 2001 From: KoroLion Date: Thu, 14 May 2020 18:17:36 +0300 Subject: [PATCH] Feature: better graphing by using gradient --- src/function_imaging.pas | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/function_imaging.pas b/src/function_imaging.pas index 8bb1345..0f50513 100644 --- a/src/function_imaging.pas +++ b/src/function_imaging.pas @@ -35,7 +35,7 @@ begin args.width := strToInt(ParamStr(1)); args.height := strToInt(ParamStr(2)); args.f := ParamStr(3); - args.zoom := StrToFloat(ParamStr(4)) * 10; + args.zoom := StrToFloat(ParamStr(4)); args.centerX := StrToFloat(ParamStr(5)); args.centerY := StrToFloat(ParamStr(6)); @@ -71,11 +71,13 @@ var fParser: TFPExpressionParser; argX, argY: TFPExprIdentifierDef; x, y, intense: integer; - convX, convY, fRes: extended; + convX, convY, fRes1, fRes2, pixelRadius: extended; + dfDx, dfDy, delta, gradLen: extended; ineq: boolean; begin setLength(pxData, args.width, args.height); fParser := TFPExpressionParser.create(nil); + pixelRadius := 1 / args.zoom; try fParser.builtIns := [bcMath]; @@ -88,7 +90,7 @@ begin for y := 0 to args.height - 1 do begin for x := 0 to args.width - 1 do begin - convX := ((x - args.width / 2) / args.zoom) + args.centerX; + convX := (x - args.width / 2) / args.zoom + args.centerX; convY := -(y - args.height / 2) / args.zoom + args.centerY; if (abs(convX) < (1 / args.zoom)) or (abs(convY) < (1 / args.zoom)) then begin @@ -104,12 +106,28 @@ begin pxData[x][y].set_color(255, 255, 255); end; end else begin - fRes := fParser.evaluate().resFloat; + fRes1 := fParser.evaluate().resFloat; - if (abs(fRes) > (1 / args.zoom)) then begin + // finding derivative of a function at this point (numeric) + delta := 0.00001; + + argX.asFloat := convX + delta; + argY.asFloat := convY; + fRes2 := fParser.evaluate().resFloat; + dfDx := (fRes2 - fRes1) / delta; + + argX.asFloat := convX; + argY.asFloat := convY + delta; + fRes2 := fParser.evaluate().resFloat; + dfDy := (fRes2 - fRes1) / delta; + + // calculating length of a gradient at this point + gradLen := sqrt(sqr(dfDx) + sqr(dfDy)); + + if (abs(fRes1) > (gradLen * pixelRadius)) then begin pxData[x][y].set_color(255, 255, 255); end else begin - intense := round(abs(fRes) / (1 / args.zoom)); + intense := round(abs(fRes1) / (gradLen * pixelRadius)); pxData[x][y].set_color(intense, intense, intense); end; end;