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

203 lines
4.9 KiB
ObjectPascal

{
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
}
unit varEpispiral;
interface
uses
BaseVariation, XFormMan;
const
EPS: double = 1E-6;
type
TVariationEpispiral = class(TBaseVariation)
private
n, thickness, holes : double;
compatible : byte;
procedure Calc7X;
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;
procedure GetCalcFunction(var f: TCalcFunction); override; // AV: for speed
end;
implementation
uses
Math;
///////////////////////////////////////////////////////////////////////////////
constructor TVariationEpispiral.Create;
begin
n := 6.0;
thickness := 0.0;
holes := 1.0;
compatible := 1;
end;
procedure TVariationEpispiral.GetCalcFunction(var f: TCalcFunction);
begin
if compatible = 1 then
f := CalcFunction
else
f := Calc7X;
end;
///////////////////////////////////////////////////////////////////////////////
procedure TVariationEpispiral.CalcFunction;
var
t, theta, da: double;
begin
theta := arctan2(FTy^, FTx^);
da := cos(n * theta);
if (abs(da) < EPS) then da := EPS;
da := 1/da;
// classic version
if (abs(thickness) > EPS) then
t := (random * thickness * da) - holes
else
t := da - holes;
FPx^ := FPx^ + vvar * t * cos(theta);
FPy^ := FPy^ + vvar * t * sin(theta);
end;
procedure TVariationEpispiral.Calc7X;
var
t, theta, da: double;
begin
theta := arctan2(FTy^, FTx^);
da := cos(n * theta);
if (abs(da) < EPS) then da := EPS;
da := 1/da;
// 7X.15D version
t := (random * thickness * da) - holes;
if (t = 0) then
begin
FPx^ := FPx^;
FPy^ := FPy^;
end
else
begin
FPx^ := FPx^ + vvar * t * cos(theta);
FPy^ := FPy^ + vvar * t * sin(theta);
end;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationEpispiral.GetInstance: TBaseVariation;
begin
Result := TVariationEpispiral.Create;
end;
///////////////////////////////////////////////////////////////////////////////
class function TVariationEpispiral.GetName: string;
begin
Result := 'Epispiral';
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationEpispiral.GetVariableNameAt(const Index: integer): string;
begin
case Index Of
0: Result := 'Epispiral_n';
1: Result := 'Epispiral_thickness';
2: Result := 'Epispiral_holes';
3: Result := 'Epispiral_old';
else
Result := '';
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationEpispiral.SetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'Epispiral_n' then begin
n := Value;
Result := True;
end else if Name = 'Epispiral_thickness' then begin
thickness := Value;
Result := True;
end
else if Name = 'Epispiral_holes' then begin
holes := Value;
Result := True;
end
else if Name = 'Epispiral_old' then begin
if (Value > 1) then Value := 1;
if (Value < 0) then Value := 0;
compatible := Round(Value);
Result := True;
end
end;
function TVariationEpispiral.ResetVariable(const Name: string): boolean;
begin
Result := False;
if Name = 'Epispiral_n' then begin
n := 6.0;
Result := True;
end else if Name = 'Epispiral_thickness' then begin
thickness := 0.0;
Result := True;
end
else if Name = 'Epispiral_holes' then begin
holes := 0.0;
Result := True;
end
else if Name = 'Epispiral_old' then begin
compatible := 1;
Result := True;
end
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationEpispiral.GetNrVariables: integer;
begin
Result := 4;
end;
///////////////////////////////////////////////////////////////////////////////
function TVariationEpispiral.GetVariable(const Name: string; var value: double): boolean;
begin
Result := False;
if Name = 'Epispiral_n' then begin
Value := n;
Result := True;
end else if Name = 'Epispiral_thickness' then begin
Value := thickness;
Result := True;
end
else if Name = 'Epispiral_holes' then begin
Value := holes;
Result := True;
end
else if Name = 'Epispiral_old' then begin
Value := compatible;
Result := True;
end;
end;
///////////////////////////////////////////////////////////////////////////////
initialization
RegisterVariation(TVariationClassLoader.Create(TVariationEpispiral), false, false);
end.