{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina } unit varDisc2; interface uses BaseVariation, XFormMan; {$ifdef CPUX86} {$define _ASM_} {$endif} type TVariationDisc2 = class(TBaseVariation) private rot, add, p, k, sinadd, cosadd: double; public constructor Create; class function GetName: string; override; class function GetInstance: TBaseVariation; override; function GetNrVariables: integer; override; function GetVariableNameAt(const Index: integer): string; override; function SetVariable(const Name: string; var value: double): boolean; override; function GetVariable(const Name: string; var value: double): boolean; override; procedure Prepare; override; procedure CalcFunction; override; end; implementation uses Math; { TVariationDisc2 } /////////////////////////////////////////////////////////////////////////////// constructor TVariationDisc2.Create; begin rot := random + 0.5; end; /////////////////////////////////////////////////////////////////////////////// procedure TVariationDisc2.Prepare; var t: double; begin p := vvar / PI; k := rot * PI; SinCos(add, sinadd, cosadd); cosadd := cosadd - 1; if (add > PI2) then begin t := 1 + add - PI2; cosadd := cosadd * t; sinadd := sinadd * t; end else if (add < -PI2) then begin t := 1 + add + PI2; cosadd := cosadd * t; sinadd := sinadd * t; end; end; /////////////////////////////////////////////////////////////////////////////// procedure TVariationDisc2.CalcFunction; {$ifndef _ASM_} var r, sinr, cosr: extended; begin SinCos(k * (FTx^ + FTy^), sinr, cosr); r := p * arctan2(FTx^, FTy^); FPx^ := FPx^ + (sinr + cosadd) * r; FPy^ := FPy^ + (cosr + sinadd) * r; {$else} asm mov edx, [eax + FTx] fld qword ptr [edx] fld qword ptr [edx + 8] fpatan fmul qword ptr [eax + p] fld qword ptr [edx] fadd qword ptr [edx + 8] fmul qword ptr [eax + k] fsincos fadd qword ptr [eax + sinadd] fmul st, st(2) fadd qword ptr [edx + 24] fstp qword ptr [edx + 24] fadd qword ptr [eax + cosadd] fmulp fadd qword ptr [edx + 16] fstp qword ptr [edx + 16] {$endif} end; /////////////////////////////////////////////////////////////////////////////// class function TVariationDisc2.GetInstance: TBaseVariation; begin Result := TVariationDisc2.Create; end; /////////////////////////////////////////////////////////////////////////////// class function TVariationDisc2.GetName: string; begin Result := 'disc2'; end; /////////////////////////////////////////////////////////////////////////////// function TVariationDisc2.GetVariableNameAt(const Index: integer): string; begin case Index Of 0: Result := 'disc2_rot'; 1: Result := 'disc2_twist'; else Result := ''; end; end; /////////////////////////////////////////////////////////////////////////////// function TVariationDisc2.SetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = 'disc2_rot' then begin rot := Value; Result := True end else if Name = 'disc2_twist' then begin add := Value; Result := True; end; end; /////////////////////////////////////////////////////////////////////////////// function TVariationDisc2.GetNrVariables: integer; begin Result := 2; end; /////////////////////////////////////////////////////////////////////////////// function TVariationDisc2.GetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = 'disc2_rot' then begin Value := rot; Result := True end else if Name = 'disc2_twist' then begin Value := add; Result := True; end; end; /////////////////////////////////////////////////////////////////////////////// initialization RegisterVariation(TVariationClassLoader.Create(TVariationDisc2), false, false); end.