📄 jmaths.pas
字号:
function MapFXY(fxy: FIXED): Longint; // = Fixed2Int
var
lxy : double;
begin
lxy := Longint(fxy);
result := Round(lxy / 65536.0);
end;
function IntFromFixed(f: FIXED): Longint; // = Fixed2Int
begin
if f.fract >= $8000 then result := f.value + 1
else result := f.value;
end;
{ *********************** Fixed-point Number function *************************}
function int2Fix(x: Longint): FIXED; assembler; register;
asm
sal eax,16;
end;
function Fix2int(x: FIXED): Longint; assembler; register;
asm
sar eax,16
end;
function FixAdd(a,b: FIXED): FIXED; assembler; register;
asm
add eax,edx
end;
function FixSub(a,b: FIXED): FIXED; assembler; register;
asm
sub eax,edx
end;
function FixRound(x: Fixed): Longint; assembler; register;
asm
add eax,$00007FFF
shr eax,16
end;
function FixMul(x,y : FIXED): FIXED; assembler; register;
asm
mov ecx,edx
imul ecx
shr eax,16
sal edx,16
or eax,edx
end;
function FixDiv(x, y: Fixed): Fixed; assembler; register;
asm
mov ecx,edx
mov edx,eax
shl eax,16
sar edx,16
idiv ecx
end;
function FixAverageA(x, y: Fixed): Fixed; assembler; register;
asm
mov ecx,2
add eax,edx
cdq
idiv ecx
end;
function FixAverageB(x,y: FIXED): FIXED;
var
l : Longint;
begin
l := (Longint(x) + Longint(y)) div 2;
result := FIXED(l);
end;
function Float2Fix(x: double): FIXED;
begin
result := FIXED(Longint(Trunc(x * 65536)));
end;
function Fix2Float(Value: FIXED): double;
begin
result := Longint(Value) * (1.0 / 65536);
end;
// ************* fp.java 16:16 Fixed-Point number Math Library v1.3 ************
function JFixToInt(x: Longint): Longint;
begin
result := x shr 16;
end;
function JIntToFix(x : Longint): Longint;
begin
result := x shl 16;
end;
function JFixMul(x,y : Longint): Longint;
var
z : Int64;
begin
z := Int64(x) * Int64(y);
result := z shr 16;
end;
function JFixDiv(x,y : Longint): Longint;
var
z : Int64;
begin
z := Int64(x) shl 32;
result := Round(z / Int64(y)) shr 16;
end;
function JFixSqrt(n : Longint): Longint;
var
i : Longint;
s : Longint;
begin
s := (n + 65536) shr 1;
for i := 0 to 7 do begin
//converge six times
s := (s + JFixDiv(n,s)) shr 1;
end;
result := s;
end;
function JFixRound(n : Longint): Longint;
var
k : Longint;
begin
if n > 0 then begin
if (n and $8000) <> 0 then begin
result := (((n + $10000) shr 16) shl 16);
exit;
end else begin
result := ((n shr 16) shl 16);
exit;
end;
end else begin
n := -n;
if (n and $8000) <> 0 then k := (((n + $10000) shr 16) shl 16)
else k := ((n shr 16) shl 16);
result := -k;
end;
end;
const
JCPI : Longint = 205887;
JCPI_OVER_2 : Longint = 102943; // JCPI / 2
JCE : Longint = 178145;
JCHALF : Longint = 2 shl 15;
// For the inverse tangent calls, all approximations are valid for |t| <= 1.
// To compute ATAN(t) for t > 1, use ATAN(t) = PI/2 - ATAN(1/t). For t < -1,
// use ATAN(t) = -PI/2 - ATAN(1/t).
JCSK1 : Longint = 498;
JCSK2 : Longint = 10882;
// Computes SIN(f), f is a fixed point number in radians.
// 0 <= f <= 2PI
// If in range -pi/4 to pi/4: nothing needs to be done.
// otherwise, we need to get f into that range and account for
// sign change.
function JFixSin(f: Longint): Longint;
var
vsign : Longint;
vsqr : Longint;
begin
vsign := 1;
if (f > JCPI_OVER_2) and (f <= JCPI) then f := JCPI - f else
if (f > JCPI) and (f <= (JCPI + JCPI_OVER_2)) then begin
f := f - JCPI;
vsign := -1;
end else
if f > (JCPI + JCPI_OVER_2) then begin
f := (JCPI shl 1) - f;
vsign := -1;
end;
vsqr := JFixMul(f,f);
result := JCSK1;
result := JFixMul(result,vsqr);
dec(result,JCSK2);
result := JFixMul(result,vsqr);
inc(result,1 shl 16);
result := JFixMul(result,f);
result := vsign * result;
end;
const
JCCK1 : Longint = 2328;
JCCK2 : Longint = 32551;
function JFixCos(f: Longint): Longint;
var
vsign : Longint;
vsqr : Longint;
begin
vsign := 1;
if (f > JCPI_OVER_2) and (f <= JCPI) then begin
f := JCPI - f;
vsign := -1;
end else
if (f > JCPI_OVER_2) and (f <= (JCPI + JCPI_OVER_2)) then begin
f := f - JCPI;
vsign := -1;
end else
if f > (JCPI + JCPI_OVER_2) then f := (JCPI shl 1) - f;
vsqr := JFixMul(f,f);
result := JCCK1;
result := JFixMul(result,vsqr);
dec(result,JCCK2);
result := JFixMul(result,vsqr);
inc(result,1 shl 16);
result := result * vsign;
end;
const
JCTK1 : Longint = 13323;
JCTK2 : Longint = 20810;
function JFixTan(f : Longint): Longint;
var
vsqr : Longint;
begin
vsqr := JFixMul(f,f);
result := JCTK1;
result := JFixMul(result,vsqr);
inc(result,JCTK2);
result := JFixMul(result,vsqr);
inc(result,1 shl 16);
result := JFixMul(result,f);
end;
function JFixArcTan(f : Longint): Longint;
var
vsqr : Longint;
begin
vsqr := JFixMul(f,f);
result := 1365;
result := JFixMul(result,vsqr);
dec(result,5579);
result := JFixMul(result,vsqr);
inc(result,11805);
result := JFixMul(result,vsqr);
dec(result,21646);
result := JFixMul(result,vsqr);
inc(result,65527);
result := JFixMul(result,f);
end;
const
JCAS1 : Longint = -1228;
JCAS2 : Longint = 4866;
JCAS3 : Longint = 13901;
JCAS4 : Longint = 102939;
function JFixArcSin(f : Longint): Longint;
var
fRoot : Longint;
begin
fRoot := JFixSqrt((1 shl 16) - f);
result := JCAS1;
result := JFixMul(result,f);
inc(result,JCAS2);
result := JFixMul(result,f);
dec(result,JCAS3);
result := JFixMul(result,f);
inc(result,JCAS4);
result := JCPI_OVER_2 - (JFixMul(fRoot,result));
end;
function JFixArcCos(f : Longint): Longint;
var
fRoot : Longint;
begin
fRoot := JFixSqrt((1 shl 16) - f);
result := JCAS1;
result := JFixMul(result,f);
inc(result,JCAS2);
result := JFixMul(result,f);
dec(result,JCAS3);
result := JFixMul(result,f);
inc(result,JCAS4);
result := JFixMul(fRoot,result);
end;
const
JCfpfact : array[0..8] of Longint =
(
65536,
65536,
131072,
393216,
1572864,
7864320,
47185920,
330301440,
-1652555776
);
function JFixExp(x : Longint): Longint;
var
x2 : Longint;
x3 : Longint;
x4 : Longint;
x5 : Longint;
x6 : Longint;
x7 : Longint;
x8 : Longint;
begin
result := 1 shl 16;
x2 := JFixMul(x,x);
x3 := JFixMul(x2,x);
x4 := JFixMul(x2,x2);
x5 := JFixMul(x4,x);
x6 := JFixMul(x4,x2);
x7 := JFixMul(x6,x);
x8 := JFixMul(x4,x4);
result := result + x +
JFixDiv(x2,JCfpfact[2]) +
JFixDiv(x3,JCfpfact[3]) +
JFixDiv(x4,JCfpfact[4]) +
JFixDiv(x5,JCfpfact[5]) +
JFixDiv(x6,JCfpfact[6]) +
JFixDiv(x7,JCfpfact[7]) +
JFixDiv(x8,JCfpfact[8]);
end;
const
JClog2arr : array[0..18] of Longint =
(
26573,
14624,
7719,
3973,
2017,
1016,
510,
256,
128,
64,
32,
16,
8,
4,
2,
1,
0,
0,
0
);
JClnscale : array[0..16] of Longint =
(
0,
45426,
90852,
136278,
181704,
227130,
272557,
317983,
363409,
408835,
454261,
499687,
545113,
590539,
635965,
681391,
726817
);
function JFixLn(x : Longint): Longint;
var
shift : Longint;
g : Longint;
d : Longint;
i : Longint;
begin
// prescale so x is between 1 and 2
shift := 0;
while x > (1 shl 17) do begin
inc(shift);
x := x shr 1;
end;
g := 0;
d := JCHALF;
for i := 1 to 15 do begin
if x > ((1 shl 16) + d) then begin
x := JFixDiv(x,(1 shl 16) + d);
inc(g,JClog2arr[i - 1]); // log2arr[i-1] = log2(1 + d);
end;
d := d shr 1;
end;
result := g + JClnscale[shift];
end;
var
JVxIntersect : Longint;
JVyIntersect : Longint;
function JFixIntersects(ax0,ay0,ax1,ay1,bx0,by0,bx1,by1: Longint): boolean;
var
adx,ady,bdx,bdy : Longint;
xma,xba,xmb,xbb : Longint;
TWO,dist,xa,xb : Longint;
minxa,maxxa,minya,maxya : Longint;
minxb,maxxb,minyb,maxyb : Longint;
begin
ax0 := ax0 shl 16;
ay0 := ay0 shl 16;
ax1 := ax1 shl 16;
ay1 := ay1 shl 16;
bx0 := bx0 shl 16;
by0 := by0 shl 16;
bx1 := bx1 shl 16;
by1 := by1 shl 16;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -