241 lines
6.2 KiB
ObjectPascal
241 lines
6.2 KiB
ObjectPascal
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
|
|
|
|
unit varHyperboloid;
|
|
|
|
interface
|
|
|
|
uses
|
|
BaseVariation, XFormMan;
|
|
|
|
type
|
|
TVariationHyperboloid = class(TBaseVariation)
|
|
private
|
|
kx, ky, kz, maxheight, h, hb: double;
|
|
vkx, vky, vkz: double;
|
|
limit, zero: byte;
|
|
|
|
procedure CalcCut;
|
|
procedure CalcCutBoarder;
|
|
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;
|
|
procedure GetCalcFunction(var f: TCalcFunction); override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math;
|
|
|
|
{ TVariationHyperboloid }
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TVariationHyperboloid.Prepare;
|
|
begin
|
|
vkx := VVAR * kx;
|
|
vky := VVAR * ky;
|
|
vkz := VVAR * kz;
|
|
h := sqrt(1 + sqr(maxheight / ky));
|
|
hb := sqrt(sqr(h) - 1);
|
|
end;
|
|
|
|
procedure TVariationHyperboloid.GetCalcFunction(var f: TCalcFunction);
|
|
begin
|
|
if (limit = 0) then
|
|
f := CalcFunction
|
|
else if (zero = 0) then
|
|
f := CalcCutBoarder
|
|
else
|
|
f := CalcCut;
|
|
end;
|
|
|
|
procedure TVariationHyperboloid.CalcFunction;
|
|
var
|
|
sn, cn, sh, ch: double;
|
|
begin
|
|
SinCos(FTx^, sn, cn);
|
|
SinhCosh(FTy^, sh, ch);
|
|
|
|
FPx^ := FPx^ + vkx * ch * sn;
|
|
FPy^ := FPy^ + vky * sh;
|
|
FPz^ := FPz^ + vkz * ch * cn;
|
|
end;
|
|
|
|
procedure TVariationHyperboloid.CalcCut;
|
|
var
|
|
sn, cn, sh, ch: double;
|
|
begin
|
|
SinhCosh(FTy^, sh, ch);
|
|
|
|
if (ch <= h) then // cut the surface
|
|
begin
|
|
SinCos(FTx^, sn, cn);
|
|
FPx^ := FPx^ + vkx * ch * sn;
|
|
FPy^ := FPy^ + vky * sh;
|
|
FPz^ := FPz^ + vkz * ch * cn;
|
|
end;
|
|
end;
|
|
|
|
procedure TVariationHyperboloid.CalcCutBoarder;
|
|
var
|
|
sn, cn, sh, ch: double;
|
|
begin
|
|
SinCos(FTx^, sn, cn);
|
|
SinhCosh(FTy^, sh, ch);
|
|
|
|
if (ch <= h) then // cut the surface
|
|
begin
|
|
FPx^ := FPx^ + vkx * ch * sn;
|
|
FPy^ := FPy^ + vky * sh;
|
|
FPz^ := FPz^ + vkz * ch * cn;
|
|
end
|
|
else begin // place the point on it's boarder
|
|
FPx^ := FPx^ + vkx * h * sn;
|
|
FPy^ := FPy^ + vky * sign(sh) * hb;
|
|
FPz^ := FPz^ + vkz * h * cn;
|
|
end;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
constructor TVariationHyperboloid.Create;
|
|
begin
|
|
kx := 1;
|
|
ky := 1;
|
|
kz := 1;
|
|
maxheight := RandomRange(3, 6);
|
|
limit := 1;
|
|
zero := 0;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class function TVariationHyperboloid.GetInstance: TBaseVariation;
|
|
begin
|
|
Result := TVariationHyperboloid.Create;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class function TVariationHyperboloid.GetName: string;
|
|
begin
|
|
Result := 'hourglass3D'; // AV: hyperbolic hyperboloid :)
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationHyperboloid.GetVariableNameAt(const Index: integer): string;
|
|
begin
|
|
case Index Of
|
|
0: Result := 'hourglass3D_kx';
|
|
1: Result := 'hourglass3D_ky';
|
|
2: Result := 'hourglass3D_kz';
|
|
3: Result := 'hourglass3D_maxheight';
|
|
4: Result := 'hourglass3D_uselimit';
|
|
5: Result := 'hourglass3D_zero_edges';
|
|
else
|
|
Result := '';
|
|
end
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationHyperboloid.SetVariable(const Name: string; var value: double): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = 'hourglass3D_kx' then begin
|
|
if (value < 1E-5) then Value := 1E-5;
|
|
kx := Value;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_ky' then begin
|
|
if (value < 1E-5) then Value := 1E-5;
|
|
ky := Value;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_kz' then begin
|
|
if (value < 1E-5) then Value := 1E-5;
|
|
kz := Value;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_maxheight' then begin
|
|
if (value < 0.1) then Value := 0.1;
|
|
maxheight := Value;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_uselimit' then begin
|
|
if (value < 0) then Value := 0;
|
|
if (value > 1) then Value := 1;
|
|
limit := Round(Value);
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_zero_edges' then begin
|
|
if (value < 0) then Value := 0;
|
|
if (value > 1) then Value := 1;
|
|
zero := Round(Value);
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function TVariationHyperboloid.ResetVariable(const Name: string): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = 'hourglass3D_kx' then begin
|
|
kx:= 1;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_ky' then begin
|
|
ky := 1;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_kz' then begin
|
|
kz := 1;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_maxheight' then begin
|
|
maxheight := 3;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_uselimit' then begin
|
|
limit := IfThen(limit = 0, 1, 0);
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_zero_edges' then begin
|
|
zero := IfThen(zero = 0, 1, 0);
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationHyperboloid.GetNrVariables: integer;
|
|
begin
|
|
Result := 6;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TVariationHyperboloid.GetVariable(const Name: string; var value: double): boolean;
|
|
begin
|
|
Result := False;
|
|
if Name = 'hourglass3D_kx' then begin
|
|
Value := kx;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_ky' then begin
|
|
Value := ky;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_kz' then begin
|
|
Value := kz;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_maxheight' then begin
|
|
Value := maxheight;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_uselimit' then begin
|
|
Value := limit;
|
|
Result := True;
|
|
end else if Name = 'hourglass3D_zero_edges' then begin
|
|
Value := zero;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
initialization
|
|
RegisterVariation(TVariationClassLoader.Create(TVariationHyperboloid), true, false);
|
|
end.
|