1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
unit Utils;
{***********************************************************
Project: C-evo External Map Generator
Copyright: 1999-2023 P Blackman
License: GPLv3+
General subroutines that don't belong anywhere else
***********************************************************}
interface
// Returns a value dependent on X, ranging from A to B,
// scaled to be bewteen 0 and 1
function JumpStep(A, B, X: Double): Double;
// fast Bias & gain functions
// scaled to work on input byte values with a percentage control
function Bias(TB, A: Integer): Integer;
function Gain(TB, A: Integer): Integer;
// Round to an integer with a probability of rounding up or down
// that is dependent on how near the value is to the upper or lower bound
function BlendRound(X: Double): Integer;
// Round small numbers up, others down, so 0.1 etc shows as non zero
function MyRound(S: Double): Integer;
// Combine gain & bias
function GainBias(val, G, B: Integer): Integer;
implementation
function MyRound(S: Double): Integer;
begin
if (S < 1) AND (S > 0.00001) then
// Round very small values up to 1
Result := 1
else
if S > 3 then
Result := Trunc(S)
else
Result := Round(S);
end;
function BlendRound(X: Double): Integer;
var Base: Integer;
Test: Double;
begin
// Offset so 0 is a full band
if X > 3.5 then
Result := 3
else
begin
X := X - 0.5;
Base := Trunc(X);
Test := 0.5; //Random;
if frac(X) > test then
Inc(base);
Result := base;
end;
end;
function JumpStep(A, B, X: Double): Double;
begin
if X < A then
Result := 0
else
if X >= B then
Result := 1
else
Result := (X - A) / (B - A);
end;
function Bias(TB, A: Integer): Integer;
var T: Double;
begin
if A <= 0 then
Result := 0
else
if A >= 100 then
Result := High(Byte)
else
begin
T := TB / High(Byte);
Result := Round(High(Byte) * T / ((100 / A - 2) * (1 - T) + 1));
end;
end;
function Gain(TB, A: Integer): Integer;
var T: Double;
begin
T := TB / High(Byte);
A := 100 - A; // Function seems to invert expected results
if A >= 100 then
Result := High(Byte) DIV 2 // 50%
else
if T < 0.5 then
if A <= 0 then
Result := 0
else
Result := Round(High(Byte) * T / ((100 / A - 2) * (1 - 2 * T) + 1))
else
if A <= 0 then
Result := High(Byte)
else
Result := Round(High(Byte) *
((100 / A - 2) * (1 - 2 * T) - T) / ((100 / A - 2) * (1 - 2 * T) - 1));
end;
function GainBias(val, G, B: Integer): Integer;
var temp1,
temp2,
Temp3: Integer;
begin
temp1 := val;
temp2 := Utils.Gain(temp1, G);
temp3 := Utils.Bias(temp2, B);
Result := temp3;
end;
end.
|