Thema: Delphi Punkt innerhalb Kreis?

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.056 Beiträge
 
Delphi 12 Athens
 
#14

Re: Punkt innerhalb Kreis?

  Alt 5. Mai 2009, 23:18
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
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat