{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina } unit varBoarders2; interface uses BaseVariation, XFormMan; const sb2c = 'boarders2_c'; sleft = 'boarders2_left'; sright = 'boarders2_right'; eps: double = 1e-30; type TVariationBoarders2 = class(TBaseVariation) private b2c, left, right, cc, cl, cr: 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; { TVariationBoarders2 } ////////////////////////////////////////// procedure TVariationBoarders2.Prepare; begin cc := abs(b2c); cl := cc * abs(left); cr := cc + (cc * abs(right)); end; ////////////////////////////////////////// procedure TVariationBoarders2.CalcFunction; var roundX, roundY, offsetX, offsetY: double; begin roundX := round(FTx^); roundY := round(FTy^); offsetX := FTx^ - roundX; offsetY := FTy^ - roundY; if (random >= cr) then begin FPx^ := FPx^ + VVAR * (offsetX * cc + roundX); FPy^ := FPy^ + VVAR * (offsetY * cc + roundY); end else begin if (abs(offsetX) >= abs(offsetY)) then begin if(offsetX >= 0.0) then begin FPx^ := FPx^ + VVAR * (offsetX * cc + roundX + cl); FPy^ := FPy^ + VVAR * (offsetY * cc + roundY + cl * offsetY / offsetX); end else begin FPx^ := FPx^ + VVAR * (offsetX * cc + roundX - cl); FPy^ := FPy^ + VVAR * (offsetY * cc + roundY - cl * offsetY / offsetX); end; end else begin if(offsetY >= 0.0) then begin FPy^ := FPy^ + VVAR * (offsetY * cc + roundY + cl); FPx^ := FPx^ + VVAR * (offsetX * cc + roundX + offsetX / offsetY * cl); end else begin FPy^ := FPy^ + VVAR * (offsetY * cc + roundY - cl); FPx^ := FPx^ + VVAR * (offsetX * cc + roundX - offsetX / offsetY * cl); end; end; end; end; /////////////////////////////////////////////////////////////////////////////// constructor TVariationBoarders2.Create; begin b2c := 0.5; left := 0.5; right := 0.5; end; /////////////////////////////////////////////////////////////////////////////// class function TVariationBoarders2.GetInstance: TBaseVariation; begin Result := TVariationBoarders2.Create; end; /////////////////////////////////////////////////////////////////////////////// class function TVariationBoarders2.GetName: string; begin Result := 'boarders2'; end; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// function TVariationBoarders2.GetVariableNameAt(const Index: integer): string; begin case Index of 0: Result := sb2c; 1: Result := sleft; 2: Result := sright; else Result := ''; end end; /////////////////////////////////////////////////////////////////////////////// function TVariationBoarders2.SetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = sb2c then begin if abs(value) = 0 then value := eps; b2c := value; Result := True; end else if Name = sleft then begin if abs(value) = 0 then value := eps; left := Value; Result := True; end else if Name = sright then begin if abs(value) = 0 then value := eps; right := Value; Result := True; end; end; function TVariationBoarders2.ResetVariable(const Name: string): boolean; begin Result := False; if Name = sb2c then begin b2c := 0.5; Result := True; end else if Name = sleft then begin left := 0.5; Result := True; end else if Name = sright then begin right := 0.5; Result := True; end; end; ///////////////////////////////////////////////////////////////////// function TVariationBoarders2.GetNrVariables: integer; begin Result := 3; end; /////////////////////////////////////////////////////////////////////////////// function TVariationBoarders2.GetVariable(const Name: string; var value: double): boolean; begin Result := False; if Name = sb2c then begin Value := b2c; Result := True; end else if Name = sleft then begin Value := left; Result := True; end else if Name = sright then begin Value := right; Result := True; end; end; /////////////////////////////////////////////////////////////////////////////// initialization RegisterVariation(TVariationClassLoader.Create(TVariationBoarders2), false, false); end.