{ 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.