Apophysis-AV/Variations/varButterfly.pas
2022-03-08 20:25:51 +03:00

161 lines
3.9 KiB
ObjectPascal

{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
unit varButterfly;
interface
uses
BaseVariation, XFormMan;
type
TVariationButterfly = class(TBaseVariation)
const
str_sx: string = 'butterfly_scale_negX';
str_sy: string = 'butterfly_scale_negY';
str_sz: string = 'butterfly_3D_shift';
private
sx, sy, sz, vpi: 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;
{ TVariationButterfly }
///////////////////////////////////////////////////////////////////////////////
procedure TVariationButterfly.Prepare;
begin
vpi := vvar * 4.0 / sqrt(3.0 * pi);
end;
procedure TVariationButterfly.CalcFunction;
var r, y2: double;
begin
y2 := FTy^ * 2.0;
r := vpi * sqrt(abs(FTy^ * FTx^)/(sqr(FTx^) + sqr(y2) + 1E-20));
if (FTy^ < 0) then begin
FPx^ := FPx^ + FTx^ * r;
FPy^ := FPy^ + r * y2;
end else begin
FPx^ := FPx^ + sx * FTx^ * r;
FPy^ := FPy^ + sy * r * y2;
end;
if (sz <> 0) then
FPz^ := FPz^ + sz * r * abs(FTx^); //* Hypot(FTx^, FTy^);
end;
///////////////////////////////////////////////////////////////////////////////
constructor TVariationButterfly.Create;
begin
sx := 1;
sy := 1;
sz := 0;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationButterfly.GetInstance: TBaseVariation;
begin
Result := TVariationButterfly.Create;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationButterfly.GetName: string;
begin
Result := 'butterfly';
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationButterfly.GetVariableNameAt(const Index: integer): string;
begin
case Index Of
0: Result := str_sx;
1: Result := str_sy;
2: Result := str_sz;
else
Result := '';
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationButterfly.SetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = str_sx then begin
if (value < 0) then value := abs(value);
sx := Value;
Result := True;
end else if Name = str_sy then begin
if (value < 0) then value := abs(value);
sy := Value;
Result := True;
end else if Name = str_sz then begin
if (value < -0.1) then value := -0.1;
sz := Value;
Result := True;
end;
end;
function TVariationButterfly.ResetVariable(const Name: string): boolean;
begin
Result := False;
if Name = str_sx then begin
sx := 1;
Result := True;
end else if Name = str_sy then begin
sy := 1;
Result := True;
end else if Name = str_sz then begin
sz := 0;
Result := True;
end;
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationButterfly.GetNrVariables: integer;
begin
Result := 3;
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationButterfly.GetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = str_sx then begin
Value := sx;
Result := True;
end else if Name = str_sy then begin
Value := sy;
Result := True;
end else if Name = str_sz then begin
Value := sz;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationButterfly), true, false);
end.