Critical fix: incorrect function conversion

This commit is contained in:
KoroLion 2020-06-21 16:24:54 +03:00
parent 565cfaa226
commit e87107e89e
2 changed files with 22 additions and 15 deletions

View File

@ -78,23 +78,32 @@ var
pxData: TPxData; pxData: TPxData;
fParser: TFPExpressionParser; fParser: TFPExpressionParser;
argX, argY: TFPExprIdentifierDef; argX, argY: TFPExprIdentifierDef;
fStr: string;
x, y, intense: integer; x, y, intense: integer;
convX, convY, fRes1, fRes2, pixelRadius: extended; convX, convY, fRes1, fRes2, pixelRadius: extended;
dfDx, dfDy, delta, gradLen: extended; dfDx, dfDy, delta, gradLen: extended;
ineq: boolean; isInequality, hasEqualSign: boolean;
begin begin
setLength(pxData, args.width, args.height); setLength(pxData, args.width, args.height);
fParser := TFPExpressionParser.create(nil); fStr := args.f;
pixelRadius := 1 / args.zoom; pixelRadius := 1 / args.zoom;
delta := 0.00001;
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 try
fParser := TFPExpressionParser.create(nil);
fParser.builtIns := [bcMath]; fParser.builtIns := [bcMath];
argX := fParser.identifiers.addFloatVariable('x', 0.0); argX := fParser.identifiers.addFloatVariable('x', 0.0);
argY := fParser.identifiers.addFloatVariable('y', 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 := fStr;
fParser.expression := args.f;
ineq := (pos('>', fParser.expression) <> 0) or (pos('>=', fParser.expression) <> 0) or (pos('<', fParser.expression) <> 0) or (pos('<=', fParser.expression) <> 0);
for y := 0 to args.height - 1 do begin for y := 0 to args.height - 1 do begin
for x := 0 to args.width - 1 do begin for x := 0 to args.width - 1 do begin
@ -107,30 +116,28 @@ begin
try try
argX.asFloat := convX; argX.asFloat := convX;
argY.asFloat := convY; argY.asFloat := convY;
if (ineq) then begin if (isInequality) then begin
if (fParser.evaluate().resBoolean) then begin if (fParser.evaluate().resBoolean) then begin
pxData[x][y].set_color(0, 0, 0); pxData[x][y].set_color(0, 0, 0);
end else begin end else begin
pxData[x][y].set_color(255, 255, 255); pxData[x][y].set_color(255, 255, 255);
end; end;
end else begin end else begin
fParser.expression := stringReplace(fParser.expression, '=', '-', []);
fRes1 := fParser.evaluate().resFloat; fRes1 := fParser.evaluate().resFloat;
// finding derivative of a function at this point (numeric) // calculating df(convX, convY)/dx
delta := 0.00001;
argX.asFloat := convX + delta; argX.asFloat := convX + delta;
argY.asFloat := convY; argY.asFloat := convY;
fRes2 := fParser.evaluate().resFloat; fRes2 := fParser.evaluate().resFloat;
dfDx := (fRes2 - fRes1) / delta; dfDx := (fRes2 - fRes1) / delta;
// calculating df(convX, convY)/dy
argX.asFloat := convX; argX.asFloat := convX;
argY.asFloat := convY + delta; argY.asFloat := convY + delta;
fRes2 := fParser.evaluate().resFloat; fRes2 := fParser.evaluate().resFloat;
dfDy := (fRes2 - fRes1) / delta; 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)); gradLen := sqrt(sqr(dfDx) + sqr(dfDy));
if (abs(fRes1) > (gradLen * pixelRadius)) then begin if (abs(fRes1) > (gradLen * pixelRadius)) then begin

View File

@ -222,7 +222,7 @@ begin
width := '512'; width := '512';
height := '512'; height := '512';
fn := 'sin(x*x*x * y*y) = cos(x*x * y*y*y)'; fn := 'sin(x*x*x * y*y) = cos(x*x * y*y*y)';
zoom := '10'; zoom := '100';
centerX := '0'; centerX := '0';
centerY := '0'; centerY := '0';
end; end;