{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina Restored Z_ZVortex variation from Apophysis Cothe's plugin pack } unit varZVortex; interface uses BaseVariation, XFormMan; type TVariationZVortex = class(TBaseVariation) private sides: integer; angle, spin: double; sds2, ang2: 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; function ResetVariable(const Name: string): boolean; override; procedure Prepare; override; procedure CalcFunction; override; end; implementation uses Math; //////////////////////// procedure TVariationZVortex.Prepare; begin sds2 := sides * 0.5 / pi; ang2 := angle * 0.5 * pi; end; procedure TVariationZVortex.CalcFunction; var r, phi, t, sn, cn, sn1, cn1: double; begin r := Math.Hypot(FTx^, FTy^); phi := arctan2(FTy^, FTx^); if (r = 0) then r := 1E-300; t := sds2 * phi + spin * Math.log2(r); // AV: these Z+ variations with lost sources are drive me crazy: // they are always use vvar in a non-linear way! t := vvar * (t - floor(t)) / sds2; sn := sin(ang2) * t + phi; cn := cos(ang2) * t - 1; SinCos(sn, sn1, cn1); FPx^ := FPx^ + (r * cn1 + FTx^ * cn); FPy^ := FPy^ + (r * sn1 + FTy^ * cn); end; constructor TVariationZVortex.Create; begin sides := random(12) + 1; angle := 2 * random - 1; spin := 2 * random - 1; end; class function TVariationZVortex.GetInstance: TBaseVariation; begin Result := TVariationZVortex.Create; end; class function TVariationZVortex.GetName: string; begin Result := 'Z_vortex'; end; function TVariationZVortex.GetNrVariables: integer; begin Result := 3; end; function TVariationZVortex.GetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = 'Z_vortex_sides' then begin value := sides; Result := True; end else if Name = 'Z_vortex_angle' then begin value := angle; Result := True; end else if Name = 'Z_vortex_spin' then begin value := spin; Result := True; end; end; function TVariationZVortex.GetVariableNameAt(const Index: integer): string; begin case Index of 0: Result := 'Z_vortex_sides'; 1: Result := 'Z_vortex_angle'; 2: Result := 'Z_vortex_spin'; else Result := ''; end; end; function TVariationZVortex.SetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = 'Z_vortex_sides' then begin if Value = 0 then Value := 1; sides := Round(value); Result := True; end else if Name = 'Z_vortex_angle' then begin angle := value; Result := True; end else if Name = 'Z_vortex_spin' then begin spin := value; Result := True; end; end; function TVariationZVortex.ResetVariable(const Name: string): boolean; begin Result := False; if Name = 'Z_vortex_sides' then begin sides := 1; Result := True; end else if Name = 'Z_vortex_angle' then begin angle := 0; Result := True; end else if Name = 'Z_vortex_spin' then begin spin := 0; Result := True; end; end; ////////////////////////////// initialization RegisterVariation(TVariationClassLoader.Create(TVariationZVortex), false, false); end.