brauchte grad mal etwas Abwechslung
Delphi-Quellcode:
Function PointInCircle(
Const aPoint, aCircleCenter: TPoint; aCircleRadius: Integer): Integer;
Var t: Integer;
Begin
Result := radius * radius;
t := a.x - b.x;
Dec(Result, t * t);
t := a.y - b.y;
Dec(Result, t * t);
If Result < 0
Then Result := NegativeValue
Else If Result > 0 ThenResult := PositiveValue;
End;
und die SquareInt würde ich (in "neueren" Delphis) als Inline-Funktion definieren
wobei der Vorschlag mit TPointInCircleResult eigentlich besser ist, aber wenn hier alle sooo auf Tempo achten? o.O
also 100.000.000 Mal ausgeführt in ... (bei mir, grad eben mal schnell in D7)
1: ~1,35 sec (0,0000135 Millisekunden)
2: ~1,25 sec (0,0000125 Millisekunden)
3: ~0,50 sec (0,0000050 Millisekunden)
4: ~0,40 sec (0,0000040 Millisekunden)
das ist alles fast nix ... wie oft wollt ihr diese Funktion denn aufrufen?
Delphi-Quellcode:
// 1
function PointInCircle(a,b:TPoint; radius:integer):integer;
function SquareInt(x:integer):integer;
// Hilfsfunktion: Quadrieren
begin
result := x * x;
end;
begin
result := Sign(SquareInt(radius) - SquareInt(a.x-b.x) - SquareInt(a.y-b.y));
end;
// 2
function PointInCircle2(a,b:TPoint; radius:integer):integer;
begin
result := Sign(radius*radius - (a.x-b.x)*(a.x-b.x) - (a.y-b.y)*(a.y-b.y));
end;
// 3
function PointInCircle3(
const a,b:TPoint; radius:integer): integer;
var t: Integer;
begin
Result := radius*radius;
t := a.x - b.x;
Dec(Result, t*t);
t := a.y - b.y;
Dec(Result, t*t);
if Result < 0
then
Result := NegativeValue
else if Result > 0
then
Result := PositiveValue;
end;
// 4
Type TPointInCircleResult = (prInsideCircle, prOnCircle, prOutOfCircle);
Function PointInCircle4(
Const aPoint, aCenter: TPoint; aRadius: Integer): TPointInCircleResult;
ASM
PUSH EDI
IMUL ECX, ECX
// aRadius := aRadius * aRadius;
MOV EDI, [EAX]
// temp := aPoint.X - aCenter.X;
SUB EDI, [EDX]
//
IMUL EDI, EDI
// temp := temp * temp;
SUB ECX, EDI
// aRadius := aRadius - temp;
MOV EDI, [EAX + 4]
// temp := aPoint.Y - aCenter.Y;
SUB EDI, [EDX + 4]
//
IMUL EDI, EDI
// temp := temp * temp;
SUB ECX, EDI
// aRadius := aRadius - temp;
TEST ECX, ECX
// if ...
JS @@neg
// ... aRadius < 0 then goto negitive
JNZ @@pos
// ... aRadius > 0 then goto positive
MOV AL, &prOnCircle
// ... else Result := prOnCircle;
POP EDI
// exit;
RET
@@neg:
// negative:
MOV AL, &prInsideCircle
// Result := prOnCircle;
POP EDI
// exit;
RET
@@pos:
// positive:
MOV AL, &prOutOfCircle
// Result := prOnCircle;
POP EDI
End;
[edit] Version 4 (
ASM) eingefügt