{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }

unit varTwinTrian;

interface
uses
  BaseVariation, XFormMan;

type
  TVariationTwinTrian = class(TBaseVariation)
  private
     angle: 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 CalcFunction; override;
  end;

implementation

uses
  Math;
  
////////////////////////

procedure TVariationTwinTrian.CalcFunction;
var  
	r, diff, sinr, cosr: double;
begin                    
  r := sqrt(sqr(FTx^) + sqr(FTy^)) * vvar;
  SinCos(r * random, sinr, cosr);
  if sinr <> 0 then
	  diff := Math.Log10(sinr * sinr) + cosr
  else
	  diff := -30;
  r := vvar * FTx^;
  FPx^ := FPx^ + r * diff;
  FPy^ := FPy^ + r * (diff - sinr * angle);
end;

constructor TVariationTwinTrian.Create;
begin
  inherited Create;
  angle := pi;
end;

class function TVariationTwinTrian.GetInstance: TBaseVariation;
begin
   Result := TVariationTwinTrian.Create;
end;

class function TVariationTwinTrian.GetName: string;
begin
   Result := 'twintrian';
end;

function TVariationTwinTrian.GetNrVariables: integer;
begin
  Result := 1;
end;

function TVariationTwinTrian.GetVariableNameAt(const Index: integer): string;
begin
  case Index Of
    0: Result := 'twintrian_angle';
  else
    Result := '';
  end;
end;

function TVariationTwinTrian.GetVariable(const Name: string; var value: double): boolean;
begin
 Result := False;
  if Name = 'twintrian_angle' then begin
    Value := angle;
    Result := True;
  end;
end;

function TVariationTwinTrian.SetVariable(const Name: string; var value: double): boolean;
begin
 Result := False;
  if Name = 'twintrian_angle' then begin
    angle := Value;
    Result := True;
  end;
end;

function TVariationTwinTrian.ResetVariable(const Name: string): boolean;
begin
 Result := False;
  if Name = 'twintrian_angle' then begin
    angle := pi;
    Result := True;
  end;
end;

//////////////////////////////
initialization
  RegisterVariation(TVariationClassLoader.Create(TVariationTwinTrian), false, false);

end.
