{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina } unit varPostBoarders2; interface uses BaseVariation, XFormMan; const sb2c = 'post_boarders2_c'; sleft = 'post_boarders2_left'; sright = 'post_boarders2_right'; eps: double = 1e-30; type TVariationPostBoarders2 = 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; { TVariationPostBoarders2 } ////////////////////////////////////////// procedure TVariationPostBoarders2.Prepare; begin cc := abs(b2c); cl := cc * abs(left); cr := cc + (cc * abs(right)); end; ////////////////////////////////////////// procedure TVariationPostBoarders2.CalcFunction; var roundX, roundY, offsetX, offsetY: double; begin roundX := round(FPx^); roundY := round(FPy^); offsetX := FPx^ - roundX; offsetY := FPy^ - roundY; if (random >= cr) then begin FPx^ := VVAR * (offsetX * cc + roundX); FPy^ := VVAR * (offsetY * cc + roundY); end else begin if (abs(offsetX) >= abs(offsetY)) then begin if(offsetX >= 0.0) then begin FPx^ := VVAR * (offsetX * cc + roundX + cl); FPy^ := VVAR * (offsetY * cc + roundY + cl * offsetY / offsetX); end else begin FPx^ := VVAR * (offsetX * cc + roundX - cl); FPy^ := VVAR * (offsetY * cc + roundY - cl * offsetY / offsetX); end; end else begin if(offsetY >= 0.0) then begin FPy^ := VVAR * (offsetY * cc + roundY + cl); FPx^ := VVAR * (offsetX * cc + roundX + offsetX / offsetY * cl); end else begin FPy^ := VVAR * (offsetY * cc + roundY - cl); FPx^ := VVAR * (offsetX * cc + roundX - offsetX / offsetY * cl); end; end; end; end; /////////////////////////////////////////////////////////////////////////////// constructor TVariationPostBoarders2.Create; begin b2c := 0.5; left := 0.5; right := 0.5; end; /////////////////////////////////////////////////////////////////////////////// class function TVariationPostBoarders2.GetInstance: TBaseVariation; begin Result := TVariationPostBoarders2.Create; end; /////////////////////////////////////////////////////////////////////////////// class function TVariationPostBoarders2.GetName: string; begin Result := 'post_boarders2'; end; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// function TVariationPostBoarders2.GetVariableNameAt(const Index: integer): string; begin case Index of 0: Result := sb2c; 1: Result := sleft; 2: Result := sright; else Result := ''; end end; /////////////////////////////////////////////////////////////////////////////// function TVariationPostBoarders2.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 TVariationPostBoarders2.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 TVariationPostBoarders2.GetNrVariables: integer; begin Result := 3; end; /////////////////////////////////////////////////////////////////////////////// function TVariationPostBoarders2.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(TVariationPostBoarders2), false, false); end.