82 function cstr(const z: hwFloat): shortstring; // Returns a shortstring representations of the hwFloat. |
82 function cstr(const z: hwFloat): shortstring; // Returns a shortstring representations of the hwFloat. |
83 function hwRound(const t: hwFloat): LongInt; inline; // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1) |
83 function hwRound(const t: hwFloat): LongInt; inline; // Does NOT really round but returns the integer representation of the hwFloat without fractional digits. (-_0_9 -> -0, _1_5 -> _1) |
84 function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. |
84 function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign. |
85 function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. |
85 function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t. |
86 function hwPow(const t: hwFloat; p: LongWord): hwFloat; inline; // Returns the power of the value |
86 function hwPow(const t: hwFloat; p: LongWord): hwFloat; inline; // Returns the power of the value |
87 function hwSqrt(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. |
87 function hwSqrt1(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. |
|
88 function hwSqrt(const x: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t. |
88 function Distance(const dx, dy: hwFloat): hwFloat; // Returns the distance between two points in 2-dimensional space, of which the parameters are the horizontal and vertical distance. |
89 function Distance(const dx, dy: hwFloat): hwFloat; // Returns the distance between two points in 2-dimensional space, of which the parameters are the horizontal and vertical distance. |
89 function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters. |
90 function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters. |
90 function AngleSin(const Angle: Longword): hwFloat; |
91 function AngleSin(const Angle: Longword): hwFloat; |
91 function AngleCos(const Angle: Longword): hwFloat; |
92 function AngleCos(const Angle: Longword): hwFloat; |
92 function vector2Angle(const x, y: hwFloat): LongInt; |
93 function vector2Angle(const x, y: hwFloat): LongInt; |
262 z.isNegative:= z1.isNegative; |
263 z.isNegative:= z1.isNegative; |
263 z.QWordValue:= z1.QWordValue + z2.QWordValue |
264 z.QWordValue:= z1.QWordValue + z2.QWordValue |
264 end |
265 end |
265 end; |
266 end; |
266 |
267 |
267 function isZero(const z: hwFloat): boolean; inline; |
268 function isZero(const z: hwFloat): boolean; inline; |
268 begin |
269 begin |
269 isZero := z.QWordValue = 0; |
270 isZero := z.QWordValue = 0; |
270 end; |
271 end; |
271 |
272 |
272 operator < (const z1, z2: hwFloat) b : boolean; inline; |
273 operator < (const z1, z2: hwFloat) b : boolean; inline; |
310 z.isNegative:= z1.isNegative xor (z2 < 0); |
311 z.isNegative:= z1.isNegative xor (z2 < 0); |
311 z.QWordValue:= z1.QWordValue * abs(z2) |
312 z.QWordValue:= z1.QWordValue * abs(z2) |
312 end; |
313 end; |
313 |
314 |
314 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
315 operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline; |
315 var t: hwFloat; |
316 var t: QWord; |
316 begin |
317 begin |
317 z.isNegative:= z1.isNegative xor z2.isNegative; |
318 z.isNegative:= z1.isNegative xor z2.isNegative; |
318 z.Round:= z1.QWordValue div z2.QWordValue; |
319 z.Round:= z1.QWordValue div z2.QWordValue; |
319 t:= z1 - z2 * z.Round; |
320 t:= z1.QWordValue - z2.QWordValue * z.Round; |
320 if t.QWordValue = 0 then |
321 z.Frac:= 0; |
321 z.Frac:= 0 |
322 |
322 else |
323 if t <> 0 then |
323 begin |
324 begin |
324 while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do |
325 while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do |
325 begin |
326 begin |
326 t.QWordValue:= t.QWordValue shl 1; |
327 t:= t shl 8; |
327 z2.QWordValue:= z2.QWordValue shl 1 |
328 z2.QWordValue:= z2.QWordValue shl 8 |
328 end; |
329 end; |
|
330 |
329 if z2.Round > 0 then |
331 if z2.Round > 0 then |
330 z.Frac:= (t.QWordValue) div (z2.Round) |
332 inc(z.QWordValue, t div z2.Round); |
331 else |
|
332 z.Frac:= 0 |
|
333 end |
333 end |
334 end; |
334 end; |
335 |
335 |
336 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
336 operator / (const z1: hwFloat; const z2: LongInt) z : hwFloat; inline; |
337 begin |
337 begin |
383 hwPow.QWordValue:= QWord(hwPow.Round) * t.Frac + QWord(hwPow.Frac) * t.Round + ((QWord(hwPow.Frac) * t.Frac) shr 32); |
383 hwPow.QWordValue:= QWord(hwPow.Round) * t.Frac + QWord(hwPow.Frac) * t.Round + ((QWord(hwPow.Frac) * t.Frac) shr 32); |
384 dec(p) |
384 dec(p) |
385 end |
385 end |
386 end; |
386 end; |
387 |
387 |
388 function hwSqrt(const t: hwFloat): hwFloat; |
388 function hwSqrt1(const t: hwFloat): hwFloat; |
389 const pwr = 8; // even value, feel free to adjust |
389 const pwr = 8; // even value, feel free to adjust |
390 rThreshold = 1 shl (pwr + 32); |
390 rThreshold = 1 shl (pwr + 32); |
391 lThreshold = 1 shl (pwr div 2 + 32); |
391 lThreshold = 1 shl (pwr div 2 + 32); |
392 var l, r: QWord; |
392 var l, r: QWord; |
393 c: hwFloat; |
393 c: hwFloat; |
394 begin |
394 begin |
395 hwSqrt.isNegative:= false; |
395 hwSqrt1.isNegative:= false; |
396 |
396 |
397 if t.Round = 0 then |
397 if t.Round = 0 then |
398 begin |
398 begin |
399 l:= t.QWordValue; |
399 l:= t.QWordValue; |
400 r:= $100000000 |
400 r:= $100000000 |
423 r:= c.QWordValue |
423 r:= c.QWordValue |
424 else |
424 else |
425 l:= c.QWordValue |
425 l:= c.QWordValue |
426 until r - l <= 1; |
426 until r - l <= 1; |
427 |
427 |
428 hwSqrt.QWordValue:= l |
428 hwSqrt1.QWordValue:= l |
429 end; |
429 end; |
|
430 |
|
431 function hwSqrt(const x: hwFloat): hwFloat; |
|
432 var r, t, s, q: QWord; |
|
433 i: integer; |
|
434 begin |
|
435 hwSqrt.isNegative:= false; |
|
436 |
|
437 t:= $4000000000000000; |
|
438 r:= 0; |
|
439 q:= x.QWordValue; |
|
440 |
|
441 for i:= 0 to 31 do |
|
442 begin |
|
443 s:= r + t; |
|
444 r:= r shr 1; |
|
445 if s <= q then |
|
446 begin |
|
447 dec(q, s); |
|
448 inc(r, t); |
|
449 end; |
|
450 t:= t shr 2; |
|
451 end; |
|
452 |
|
453 hwSqrt.QWordValue:= r shl 16 |
|
454 end; |
|
455 |
|
456 |
430 |
457 |
431 function Distance(const dx, dy: hwFloat): hwFloat; |
458 function Distance(const dx, dy: hwFloat): hwFloat; |
432 begin |
459 var r: QWord; |
433 Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) |
460 begin |
|
461 r:= dx.QWordValue or dy.QWordValue; |
|
462 |
|
463 if r < $10000 then |
|
464 begin |
|
465 Distance.QWordValue:= r; |
|
466 Distance.isNegative:= false |
|
467 end else |
|
468 Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy)) |
434 end; |
469 end; |
435 |
470 |
436 function DistanceI(const dx, dy: LongInt): hwFloat; |
471 function DistanceI(const dx, dy: LongInt): hwFloat; |
437 begin |
472 begin |
438 DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) |
473 DistanceI:= hwSqrt(int2hwFloat(sqr(dx) + sqr(dy))) |