Thema: Delphi Punkt innerhalb Kreis?

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

Re: Punkt innerhalb Kreis?

  Alt 5. Mai 2009, 22: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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat