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

unit varPopcorn2;

interface

uses
  BaseVariation, XFormMan;

type
  TVariationPopcorn2 = class(TBaseVariation)
  private
    p2x, p2y, p2c: 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;

{ TVariationPopcorn2 }

///////////////////////////////////////////////////////////////////////////////

procedure TVariationPopcorn2.CalcFunction;
var
  sn, cn : double;
begin
  SinCos(p2c * FTy^, sn, cn);
  if cn <> 0 then  // AV: safety tangent
	  sn := sin(sn / cn)
  else 
	  sn := 0;
  FPx^ := FPx^ + vvar * (FTx^ + p2x * sn);
  SinCos(p2c * FTx^, sn, cn);
  if cn <> 0 then  // AV: safety tangent
	  sn := sin(sn / cn)
  else 
	  sn := 0;
  FPy^ := FPy^ + vvar * (FTy^ + p2y * sn);
end;

///////////////////////////////////////////////////////////////////////////////
class function TVariationPopcorn2.GetName: string;
begin
  Result := 'popcorn2';
end;

///////////////////////////////////////////////////////////////////////////////
function TVariationPopcorn2.GetVariableNameAt(const Index: integer): string;
begin
  case Index Of
  0: Result := 'popcorn2_x';
  1: Result := 'popcorn2_y';
  2: Result := 'popcorn2_c';
  else
    Result := '';
  end
end;

///////////////////////////////////////////////////////////////////////////////
function TVariationPopcorn2.GetNrVariables: integer;
begin
  Result := 3;
end;

///////////////////////////////////////////////////////////////////////////////
function TVariationPopcorn2.SetVariable(const Name: string; var value: double): boolean;
begin
  Result := False;
  if Name = 'popcorn2_x' then begin
    p2x := Value;
    Result := True;
  end else if Name = 'popcorn2_y' then begin
    p2y := Value;
    Result := True;
  end else if Name = 'popcorn2_c' then begin
    p2c := Value;
    Result := True;
  end;
end;

function TVariationPopcorn2.ResetVariable(const Name: string): boolean;
begin
  Result := False;
  if Name = 'popcorn2_x' then begin
    p2x := 0.1;
    Result := True;
  end else if Name = 'popcorn2_y' then begin
    p2y := 0.1;
    Result := True;
  end else if Name = 'popcorn2_c' then begin
    p2c := 3;
    Result := True;
  end;
end;


///////////////////////////////////////////////////////////////////////////////
function TVariationPopcorn2.GetVariable(const Name: string; var value: double): boolean;
begin
  Result := False;
  if Name = 'popcorn2_x' then begin
    Value := p2x;
    Result := True;
  end else if Name = 'popcorn2_y' then begin
    Value := p2y;
    Result := True;
  end else if Name = 'popcorn2_c' then begin
    Value := p2c;
    Result := True;
  end;
end;

///////////////////////////////////////////////////////////////////////////////
constructor TVariationPopcorn2.Create;
begin
  p2c := 3;
  p2x  := 0.1;
  p2y := 0.1;
end;

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

///////////////////////////////////////////////////////////////////////////////
initialization
  RegisterVariation(TVariationClassLoader.Create(TVariationPopcorn2), false, false);
end.
