193 lines
4.6 KiB
ObjectPascal
193 lines
4.6 KiB
ObjectPascal
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
|
|
|
|
unit varCpow3;
|
|
|
|
interface
|
|
|
|
uses
|
|
BaseVariation, XFormMan;
|
|
|
|
const
|
|
sr = 'cpow3_r';
|
|
sd = 'cpow3_d';
|
|
sdivisor = 'cpow3_divisor';
|
|
sspread = 'cpow3_spread';
|
|
|
|
type
|
|
TVariationCpow3 = class(TBaseVariation)
|
|
private
|
|
r, d1, spread: double;
|
|
divisor: integer;
|
|
|
|
ang, a2, d2, half_d, c2, half_c, coeff: 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;
|
|
|
|
{ TVariationCpow3 }
|
|
|
|
//////////////////////////////////////////
|
|
procedure TVariationCpow3.Prepare;
|
|
var ca, sa: double;
|
|
begin
|
|
ang := PI2 / divisor;
|
|
if (d1 < 0) then
|
|
a2 := arctan2(-ln(-d1) * r, PI2)
|
|
else
|
|
a2 := arctan2(ln(d1) * r, PI2);
|
|
SinCos(a2, sa, ca);
|
|
c2 := ca * r * ca / divisor;
|
|
d2 := ca * r * sa / divisor;
|
|
half_c := c2 * 0.5;
|
|
half_d := d2 * 0.5;
|
|
if (d2 = 0) then
|
|
coeff := 0
|
|
else
|
|
coeff := -0.095 * spread / d2;
|
|
end;
|
|
|
|
//////////////////////////////////////////
|
|
procedure TVariationCpow3.CalcFunction;
|
|
var t, sn, cn, r2, lnr2: double;
|
|
begin
|
|
t := arctan2(FTy^, FTx^);
|
|
if (t < 0) then t := t + PI2;
|
|
if (cos(t * 0.5) < (2 * random - 1)) then
|
|
t := t - PI2;
|
|
if (random < 0.5) then
|
|
t := t + PI2 * round(ln(random) * coeff)
|
|
else
|
|
t := t - PI2 * round(ln(random) * coeff);
|
|
lnr2 := ln(FTx^ * FTx^ + FTy^ * FTy^);
|
|
r2 := vvar * exp(half_c * lnr2 - d2 * t);
|
|
SinCos(c2 * t + half_d * lnr2 + ang * random(32767), sn, cn);
|
|
|
|
FPx^ := FPx^ + r2 * cn;
|
|
FPy^ := FPy^ + r2 * sn;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
constructor TVariationCpow3.Create;
|
|
begin
|
|
r := 1;
|
|
d1 := 1;
|
|
divisor := 1;
|
|
spread := 1;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class function TVariationCpow3.GetInstance: TBaseVariation;
|
|
begin
|
|
Result := TVariationCpow3.Create;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class function TVariationCpow3.GetName: string;
|
|
begin
|
|
Result := 'cpow3';
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationCpow3.GetVariableNameAt(const Index: integer): string;
|
|
begin
|
|
case Index of
|
|
0: Result := sr;
|
|
1: Result := sd;
|
|
2: Result := sdivisor;
|
|
3: Result := sspread;
|
|
else
|
|
Result := '';
|
|
end
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationCpow3.SetVariable(const Name: string; var value: double): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = sr then begin
|
|
r := Value;
|
|
Result := True;
|
|
end else if Name = sd then begin
|
|
if (Value = 0) then Value := 1;
|
|
d1 := value;
|
|
Result := True;
|
|
end else if Name = sdivisor then begin
|
|
if (Value = 0) then Value := 1;
|
|
divisor := Round(Value);
|
|
Result := True;
|
|
end else if Name = sspread then begin
|
|
spread := Value;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function TVariationCpow3.ResetVariable(const Name: string): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = sr then begin
|
|
r := 1;
|
|
Result := True;
|
|
end else if Name = sd then begin
|
|
d1 := 1;
|
|
Result := True;
|
|
end else if Name = sspread then begin
|
|
spread := 1;
|
|
Result := True;
|
|
end else if Name = sdivisor then begin
|
|
divisor := 1;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
function TVariationCpow3.GetNrVariables: integer;
|
|
begin
|
|
Result := 4;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationCpow3.GetVariable(const Name: string; var value: double): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = sr then begin
|
|
Value := r;
|
|
Result := true;
|
|
end
|
|
else if Name = sd then begin
|
|
Value := d1;
|
|
Result := true;
|
|
end else if Name = sspread then begin
|
|
Value := spread;
|
|
Result := true;
|
|
end else if Name = sdivisor then begin
|
|
Value := divisor;
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
initialization
|
|
RegisterVariation(TVariationClassLoader.Create(TVariationCpow3), false, false);
|
|
end.
|