From e87107e89eee4747a9208f5de7b9ee0f0cb19832 Mon Sep 17 00:00:00 2001 From: KoroLion Date: Sun, 21 Jun 2020 16:24:54 +0300 Subject: [PATCH] Critical fix: incorrect function conversion --- src/function_imaging.pas | 35 +++++++++++++++++++++-------------- src/gui/gui.pas | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/function_imaging.pas b/src/function_imaging.pas index 85c2335..8eb9566 100644 --- a/src/function_imaging.pas +++ b/src/function_imaging.pas @@ -78,24 +78,33 @@ var pxData: TPxData; fParser: TFPExpressionParser; argX, argY: TFPExprIdentifierDef; + fStr: string; x, y, intense: integer; convX, convY, fRes1, fRes2, pixelRadius: extended; dfDx, dfDy, delta, gradLen: extended; - ineq: boolean; + isInequality, hasEqualSign: boolean; begin setLength(pxData, args.width, args.height); - fParser := TFPExpressionParser.create(nil); + fStr := args.f; pixelRadius := 1 / args.zoom; + delta := 0.00001; - try + isInequality := (pos('>', fStr) <> 0) or (pos('>=', fStr) <> 0) or (pos('<', fStr) <> 0) or (pos('<=', fStr) <> 0); + // line is drawn in point (x, y) if f(x, y) ~= 0 + // so we changing y = x - 10 to y - (x - 10) + hasEqualSign := pos('=', fStr) <> 0; + if (hasEqualSign) then begin + fStr := stringReplace(fStr, '=', '-(', []); + fStr := fStr + ')'; + end; + + try + fParser := TFPExpressionParser.create(nil); fParser.builtIns := [bcMath]; argX := fParser.identifiers.addFloatVariable('x', 0.0); argY := fParser.identifiers.addFloatVariable('y', 0.0); - //fParser.expression := 'sin(x*x*x * y*y) - cos(x*x * y*y*y)'; - fParser.expression := args.f; - - ineq := (pos('>', fParser.expression) <> 0) or (pos('>=', fParser.expression) <> 0) or (pos('<', fParser.expression) <> 0) or (pos('<=', fParser.expression) <> 0); - + fParser.expression := fStr; + 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; @@ -107,30 +116,28 @@ begin try argX.asFloat := convX; argY.asFloat := convY; - if (ineq) then begin + if (isInequality) then begin if (fParser.evaluate().resBoolean) then begin pxData[x][y].set_color(0, 0, 0); end else begin pxData[x][y].set_color(255, 255, 255); end; end else begin - fParser.expression := stringReplace(fParser.expression, '=', '-', []); fRes1 := fParser.evaluate().resFloat; - // finding derivative of a function at this point (numeric) - delta := 0.00001; - + // calculating df(convX, convY)/dx argX.asFloat := convX + delta; argY.asFloat := convY; fRes2 := fParser.evaluate().resFloat; dfDx := (fRes2 - fRes1) / delta; + // calculating df(convX, convY)/dy argX.asFloat := convX; argY.asFloat := convY + delta; fRes2 := fParser.evaluate().resFloat; dfDy := (fRes2 - fRes1) / delta; - // calculating length of a gradient at this point + // calculating length of a gradient at (convX, convY) gradLen := sqrt(sqr(dfDx) + sqr(dfDy)); if (abs(fRes1) > (gradLen * pixelRadius)) then begin diff --git a/src/gui/gui.pas b/src/gui/gui.pas index 642ed72..329a185 100644 --- a/src/gui/gui.pas +++ b/src/gui/gui.pas @@ -222,7 +222,7 @@ begin width := '512'; height := '512'; fn := 'sin(x*x*x * y*y) = cos(x*x * y*y*y)'; - zoom := '10'; + zoom := '100'; centerX := '0'; centerY := '0'; end;