Apophysis-AV/Variations/varJulia.pas

236 lines
4.6 KiB
ObjectPascal

{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
unit varJulia;
interface
uses
{$ifdef CPUX86}
AsmRandom,
{$endif}
BaseVariation, XFormMan;
{$ifdef CPUX86}
{$define _ASM_}
{$endif}
type
TVariationJulia = class(TBaseVariation)
private
old: byte;
vvar2: double;
procedure CalcPlugin;
public
constructor Create;
class function GetName: string; override;
class function GetInstance: TBaseVariation; override;
function GetNrVariables: integer; override;
function GetVariableNameAt(const IndJulia: integer): string; override;
function SetVariable(const Name: string; var value: double): boolean; override;
function GetVariable(const Name: string; var value: double): boolean; override;
function ResetVariable(const Name: string): boolean; override;
procedure Prepare; override;
procedure CalcFunction; override;
procedure GetCalcFunction(var f: TCalcFunction); override;
end;
implementation
uses
Math;
////////////////////////
procedure TVariationJulia.Prepare;
begin
vvar2 := vvar * sqrt(2) * 0.5;
end;
procedure TVariationJulia.GetCalcFunction(var f: TCalcFunction);
begin
if old = 1 then f := CalcFunction
else f := CalcPlugin;
end;
procedure TVariationJulia.CalcFunction;
{$ifndef _ASM_}
var
r: double;
begin
(*
// AV: oriiginal code was:
FAngle := arctan2(FTx^, FTy^) / 2;
SinCos(FAngle + pi * random(2), sina, cosa);
r := vvar * sqrt(sqrt(sqrt(sqr(FTx^) + sqr(FTy^)));
FPx^ := FPx^ + r * cosa;
FPy^ := FPy^ + r * sina;
// AV: I simplified calculations
*)
r := sqrt(sqrt(sqr(FTx^) + sqr(FTy^)) + FTy^ );
if random(2) = 0 then begin
FPx^ := FPx^ + vvar2 * r;
FPy^ := FPy^ + vvar2 / r * FTx^;
end
else begin
FPx^ := FPx^ - vvar2 * r;
FPy^ := FPy^ - vvar2 / r * FTx^;
end;
{$else}
asm
mov edx, [eax + FTx]
fld qword ptr [edx] // FTx
fld qword ptr [edx + 8] // FTy
fld st(1) // FTx
fmul st,st // sqr(FTx)
fld st(1) // FTy
fmul st,st // sqr(FTy)
faddp
fsqrt
faddp
fsqrt
fld qword ptr [eax + vvar2]
mov ecx,eax
mov eax,2
call AsmRandInt
shr eax,1
jc @skip
fchs
@skip:
fmul st(2),st
fmul st,st(1)
mov edx, [ecx + FPx]
fadd qword ptr [edx]
fstp qword ptr [edx]
fdivp st(1),st
fadd qword ptr [edx + 8]
fstp qword ptr [edx + 8]
fwait
{$endif}
end;
procedure TVariationJulia.CalcPlugin;
{$ifndef _ASM_}
var
r: double;
begin
r := sqrt(sqrt(sqr(FTx^) + sqr(FTy^)) + FTx^ );
if random(2) = 0 then begin
FPx^ := FPx^ + vvar2 * r;
FPy^ := FPy^ + vvar2 / r * FTy^;
end
else begin
FPx^ := FPx^ - vvar2 * r;
FPy^ := FPy^ - vvar2 / r * FTy^;
end;
{$else}
asm
mov edx, [eax + FTx]
fld qword ptr [edx + 8] // FTy
fld qword ptr [edx] // FTx
fld st(1)
fmul st,st
fld st(1)
fmul st,st
faddp
fsqrt
faddp
fsqrt
fld qword ptr [eax + vvar2]
mov ecx,eax
mov eax,2
call AsmRandInt
shr eax,1
jc @skip
fchs
@skip:
fmul st(2),st
fmul st,st(1)
mov edx, [ecx + FPx]
fadd qword ptr [edx]
fstp qword ptr [edx]
fdivp st(1),st
fadd qword ptr [edx + 8]
fstp qword ptr [edx + 8]
fwait
{$endif}
end;
constructor TVariationJulia.Create;
begin
old := 1;
end;
class function TVariationJulia.GetInstance: TBaseVariation;
begin
Result := TVariationJulia.Create;
end;
class function TVariationJulia.GetName: string;
begin
Result := 'julia';
end;
function TVariationJulia.GetNrVariables: integer;
begin
Result := 1;
end;
function TVariationJulia.GetVariable(const Name: string;
var value: double): boolean;
begin
Result := False;
if Name = 'julia_old' then begin
value := old;
Result := True;
end;
end;
function TVariationJulia.GetVariableNameAt(const IndJulia: integer): string;
begin
case IndJulia of
0: Result := 'julia_old';
else
Result := '';
end;
end;
function TVariationJulia.SetVariable(const Name: string;
var value: double): boolean;
begin
Result := False;
if Name = 'julia_old' then begin
if Value < 0 then Value := 0;
if Value > 1 then Value := 1;
old := Round(value);
Result := True;
end;
end;
function TVariationJulia.ResetVariable(const Name: string): boolean;
begin
Result := False;
if Name = 'julia_old' then begin
old := 1;
Result := True;
end;
end;
//////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationJulia), false, false);
end.