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,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

View File

@ -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;